Python列表排序取决于项目是否在另一个列表中

时间:2021-03-06 18:06:10

Say I have a list:

说我有一个清单:

A = [1,2,3,4,5,6,7,8,9,0]

and a second list:

和第二个清单:

B = [3,6,9]

What is the best way to sort list A so that anything that matches an item in list B will appear at the beginning so that the result would be:

排序列表A的最佳方法是什么,以便匹配列表B中的项目的任何内容都将出现在开头,以便结果为:

[3,6,9,1,2,4,5,7,8,0]

5 个解决方案

#1


11  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> sorted(A,key=lambda e: e not in B)
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

How this works:

这是如何工作的:

sorted sorts an interable based on the result of key(element) for each element (the default value for key is None which results in it sorting based on the elements directly).

基于每个元素的键(元素)的结果对sort进行排序(key的默认值为None,这导致它直接基于元素进行排序)。

In our case the lambda lambda e: e not in B will return either True if e isn't in B, or False if e is in B. The element's with False's get sorted to the front, and you end up with your result. As demonstrated by:

在我们的例子中,lambda lambda e:e不在B中将返回True,如果e不在B中,或者如果e在B中则返回False。带有False的元素将被排序到前面,最后得到结果。如下所示:

>>> sorted([True,False,False])
[False, False, True]

#2


3  

Many of these answers are using set logic explicitly. But Python has it built in. If, as you say, the order doesn't matter as long as the B parts come first, this will take care of the rest:

其中许多答案都明确使用了set逻辑。但是Python内置了它。如果你说的话,只要B部分排在第一位,顺序无关紧要,这将照顾其余部分:

B = set(B)
list(B.intersection(A)) + list(set(A) - B)

This assumes that (as in your example) there are no duplicate values. If there are, use one of the list comprehension answers.

这假定(如您的示例中)没有重复值。如果有,请使用列表理解答案之一。

#3


2  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> [i for i in B if i in A] + [i for i in A if i not in B]
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

#4


2  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> b = set(B)
>>> sorted(A, key=b.__contains__, reverse=True)
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

#5


0  

Note: this will remove duplicate values - but works given unique keys.

注意:这将删除重复值 - 但是可以使用唯一键。

If both are already sorted (or otherwise ordered as you wish), then you can use:

如果两者都已经排序(或按照您的意愿订购),那么您可以使用:

A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
B = [3, 6, 9]

from collections import OrderedDict
from itertools import chain

print list(OrderedDict.fromkeys(chain(B, A)))
# [3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

Otherwise, just apply sorted to A, B or both...

否则,只需将分类应用于A,B或两者......

#1


11  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> sorted(A,key=lambda e: e not in B)
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

How this works:

这是如何工作的:

sorted sorts an interable based on the result of key(element) for each element (the default value for key is None which results in it sorting based on the elements directly).

基于每个元素的键(元素)的结果对sort进行排序(key的默认值为None,这导致它直接基于元素进行排序)。

In our case the lambda lambda e: e not in B will return either True if e isn't in B, or False if e is in B. The element's with False's get sorted to the front, and you end up with your result. As demonstrated by:

在我们的例子中,lambda lambda e:e不在B中将返回True,如果e不在B中,或者如果e在B中则返回False。带有False的元素将被排序到前面,最后得到结果。如下所示:

>>> sorted([True,False,False])
[False, False, True]

#2


3  

Many of these answers are using set logic explicitly. But Python has it built in. If, as you say, the order doesn't matter as long as the B parts come first, this will take care of the rest:

其中许多答案都明确使用了set逻辑。但是Python内置了它。如果你说的话,只要B部分排在第一位,顺序无关紧要,这将照顾其余部分:

B = set(B)
list(B.intersection(A)) + list(set(A) - B)

This assumes that (as in your example) there are no duplicate values. If there are, use one of the list comprehension answers.

这假定(如您的示例中)没有重复值。如果有,请使用列表理解答案之一。

#3


2  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> [i for i in B if i in A] + [i for i in A if i not in B]
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

#4


2  

>>> A = [1,2,3,4,5,6,7,8,9,0]
>>> B = [3,6,9]
>>> b = set(B)
>>> sorted(A, key=b.__contains__, reverse=True)
[3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

#5


0  

Note: this will remove duplicate values - but works given unique keys.

注意:这将删除重复值 - 但是可以使用唯一键。

If both are already sorted (or otherwise ordered as you wish), then you can use:

如果两者都已经排序(或按照您的意愿订购),那么您可以使用:

A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
B = [3, 6, 9]

from collections import OrderedDict
from itertools import chain

print list(OrderedDict.fromkeys(chain(B, A)))
# [3, 6, 9, 1, 2, 4, 5, 7, 8, 0]

Otherwise, just apply sorted to A, B or both...

否则,只需将分类应用于A,B或两者......