python排序两个列表

时间:2012-12-02 10:25:57

标签: python list sorting

我正在尝试将两个列表排在一起:

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]

我该怎么办?我不想使用循环进行冒泡排序。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:32)

使用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]]

答案 1 :(得分:5)

这里的技巧是当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]

答案 2 :(得分: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)从每个元组中获取第一个元素,该元素属于第一个列表。