且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何以完全相同的方式对两个列表(相互引用)进行排序

更新时间:2023-11-29 19:38:52

解决此问题的一种经典方法是使用装饰,排序,不装饰"的习惯用法,使用python内置的zip函数特别简单:

One classic approach to this problem is to use the "decorate, sort, undecorate" idiom, which is especially simple using python's built-in zip function:

>>> list1 = [3,2,4,1, 1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2 
('one', 'one2', 'two', 'three', 'four')

这些当然不再是列表,但是如果需要的话,很容易纠正:

These of course are no longer lists, but that's easily remedied, if it matters:

>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']

值得注意的是,以上可能会为简洁而牺牲速度;就地版,占用3行,对于我的小型列表来说,在我的机器上快了一点:

It's worth noting that the above may sacrifice speed for terseness; the in-place version, which takes up 3 lines, is a tad faster on my machine for small lists:

>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop

另一方面,对于较大的列表,单行版本可能会更快:

On the other hand, for larger lists, the one-line version could be faster:

>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop

正如Quantum7指出的那样, JSF的建议仍然要快一些,但可能只会有点更快,因为Python在内部使用了非常相同的DSU习惯用法用于所有基于键的排序.它只是在接近裸机的地方发生. (这表明zip例程的优化程度如何!)

As Quantum7 points out, JSF's suggestion is a bit faster still, but it will probably only ever be a little bit faster, because Python uses the very same DSU idiom internally for all key-based sorts. It's just happening a little closer to the bare metal. (This shows just how well optimized the zip routines are!)

我认为基于zip的方法更灵活并且更具可读性,所以我更喜欢它.

I think the zip-based approach is more flexible and is a little more readable, so I prefer it.