说我有两个清单:
list1 = [3, 2, 4, 1, 1] list2 = ['three', 'two', 'four', 'one', 'one2']
如果我运行list1.sort(),它将对其进行排序,[1,1,2,3,4]但是还有没有一种list2同步的方法(因此我可以说item4属于'three')?因此,预期输出为:
list1.sort()
[1,1,2,3,4]
list2
4
'three'
list1 = [1, 1, 2, 3, 4] list2 = ['one', 'one2', 'two', 'three', 'four']
我的问题是我有一个非常复杂的程序,可以很好地处理列表,但是我有点需要开始引用一些数据。我知道这对字典来说是一个完美的情况,但是我在处理过程中尽量避免使用字典,因为我确实需要对键值进行排序(如果必须使用字典,我知道如何使用它们)。
基本上,该程序的本质是,数据按随机顺序出现(如上),我需要对其进行排序,处理然后发送结果(顺序无关紧要,但是用户需要知道哪个结果属于哪个结果)键)。我考虑过先将其放入字典中,然后再对列表进行排序,但是如果不保持顺序(如果将结果传达给用户,可能会产生影响),我将无法区分具有相同值的项。因此,理想情况下,一旦获得列表,我宁愿想出一种将两个列表排序在一起的方法。这可能吗?
解决此问题的一种经典方法是使用“装饰,排序,未装饰”习惯用法,使用python的内置zip函数特别简单:
zip
>>> 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')
这些当然不再是列表,但是如果需要的话,很容易纠正:
>>> 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行,在我的机器上,对于较小的列表来说,快了一点:
>>> %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
另一方面,对于较大的列表,单行版本可能会更快:
>>> %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指出的那样,[SF的建仍然要快一些,但可能只会更快一些,因为Python内部在所有基于键的排序中使用了完全相同的DSU习惯用法。它只是在接近裸机的地方发生。(这表明zip例程的优化程度如何!)
我认为zip基于方法的灵活性更高,可读性更好,所以我更喜欢它。