2012-12-02 149 views
21

我想两个列表一起排序:蟒蛇排序两个列表

list1 = [1, 2, 5, 4, 4, 3, 6] 
list2 = [3, 2, 1, 2, 1, 7, 8] 

list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2)))) 

无论如何,这样做使我对输出

list1 = [1, 2, 3, 4, 4, 5, 6] 
list2 = [3, 2, 7, 1, 2, 1, 8] 

,同时我希望保持原始的订单数量相等4在第一个列表中:我想要的是

list1 = [1, 2, 3, 4, 4, 5, 6] 
list2 = [3, 2, 7, 2, 1, 1, 8] 

我该怎么做?我不想使用循环进行气泡排序。任何帮助赞赏。

+0

不确定你的要求,你能更具体吗? –

+3

@ShawnZhang在list1中保留list2中相同项目的初始订单。 –

+0

[Bubble sorting](http://en.wikipedia.org/wiki/Bubble_sort)是一种需要循环的特定算法。另请注意,您的第二个输出不等同于冒泡排序输出。 –

回答

31

使用key参数进行排序,该参数仅比较该对中的第一个元素。由于Python的排序是稳定的,这保证了当第一个元素相等时第二个元素的顺序保持不变。

>>> from operator import itemgetter 
>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=itemgetter(0)))] 
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]] 

即相当于:

>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0]))] 
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]] 
+0

+1。这很棒。非常感谢你救了我。 –

4

这里的诀窍在于,当Python做元组比较,它的元件,以便从左至右进行比较(例如,(4, 1) < (4, 2),这是原因你没有得到你想要在你的特定情况下的顺序)。这意味着您需要将key参数传递给sorted函数,该函数告诉它只使用对元组的第一个元素作为其排序表达式,而不是整个元组。

这是保证你想保留,因为排序:

排序是保证是稳定的。这意味着当多个记录具有相同的密钥时,它们的原始顺序将被保留。

(source)

>>> list1 = [1, 2, 5, 4, 4, 3, 6] 
>>> list2 = [3, 2, 1, 2, 1, 7, 8] 
>>> 
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0]))) 
>>> 
>>> print list1 
[1, 2, 3, 4, 4, 5, 6] 
>>> print list2 
[3, 2, 7, 2, 1, 1, 8] 
0

在你的代码排序进行基础上在第一和元组的第二元件,因此所得到的第二列表中的元素是在排序顺序的相同的元件第一个列表。

为了避免基于所述第二列表上排序,只是指定只从所述第一列表中的元素应在元组的比较中使用:

>>> from operator import itemgetter 
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2),key=itemgetter(0)))) 
>>> list1, list2 
([1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]) 

itemgetter(0)取第一元件从每个元组,这属于第一个列表。