如何以完全相同的方式对两个列表(相互引用)进行排序 [英] How to sort two lists (which reference each other) in the exact same way

查看:123
本文介绍了如何以完全相同的方式对两个列表(相互引用)进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有两个列表:

list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']

如果我运行list1.sort(),它将把它排序为[1,1,2,3,4],但是是否也有办法使list2保持同步(所以我可以说项目4属于'three')?因此,预期的输出将是:

If I run list1.sort(), it'll sort it to [1,1,2,3,4] but is there a way to get list2 in sync as well (so I can say item 4 belongs to 'three')? So, the expected output would be:

list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']

我的问题是我有一个非常复杂的程序,可以很好地处理列表,但是我有点需要开始引用一些数据.我知道这对字典来说是一个完美的情况,但是我在处理过程中尽量避免使用字典,因为我确实需要对键值进行排序(如果必须使用字典,我知道如何使用它们).

My problem is I have a pretty complex program that is working fine with lists but I sort of need to start referencing some data. I know this is a perfect situation for dictionaries but I'm trying to avoid dictionaries in my processing because I do need to sort the key values (if I must use dictionaries I know how to use them).

该程序的本质是,数据按随机顺序排列(如上),我需要对其进行排序,处理然后发送结果(顺序无关紧要,但是用户需要知道哪个结果属于哪个键).我考虑过先将其放入字典中,然后再对列表进行排序,但是如果不保持顺序(如果将结果传达给用户,可能会产生影响),我将无法区分具有相同值的项.因此,理想情况下,一旦获得列表,我宁愿找出一种将两个列表排序在一起的方法.这可能吗?

Basically the nature of this program is, the data comes in a random order (like above), I need to sort it, process it and then send out the results (order doesn't matter but users need to know which result belongs to which key). I thought about putting it in a dictionary first, then sorting list one but I would have no way of differentiating of items in the with the same value if order is not maintained (it may have an impact when communicating the results to users). So ideally, once I get the lists I would rather figure out a way to sort both lists together. Is this possible?

推荐答案

解决此问题的一种经典方法是使用装饰,排序,不装饰"的习惯用法,使用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.

这篇关于如何以完全相同的方式对两个列表(相互引用)进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆