按另一个列表中项目的存在对列表进行排序

Wil*_*iam 5 python sorting list

假设我有两个列表:

a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']
Run Code Online (Sandbox Code Playgroud)

您将如何最有效地对其进行排序,例如:

列表b相对于 进行排序a。中的唯一元素b应放在排序列表的末尾。中的唯一元素a可以被忽略。

示例输出:

c = ['30', '17', '60', '1201', '900']
Run Code Online (Sandbox Code Playgroud)

对不起,这是一个简单的问题。我的尝试停留在十字路口。

intersection = sorted(set(a) & set(b), key = a.index)
Run Code Online (Sandbox Code Playgroud)

yat*_*atu 6

您可以创建一个自定义字典,键是条目,a值是它们的位置。然后b根据字典中的值进行排序。您可以dict.get用于查找,inf如果该值不存在:

a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']

d = {i:ix for ix, i in enumerate(a)}
#{'30': 0, '10': 1, '90': 2, '1111': 3, '17': 4}
sorted(b, key=lambda x: d.get(x, float('inf')))
#['30', '17', '60', '1201', '900']
Run Code Online (Sandbox Code Playgroud)


kay*_*ya3 6

没有必要在这里实际排序。您需要 ina中的元素,其b顺序与它们在 中的顺序相同a;后跟b不在 中的元素,其a顺序与在 中的顺序相同b。

我们可以使用两个过滤器来做到这一点,使用集合进行快速成员资格测试:

>>> a = ['30', '10', '90', '1111', '17']
>>> b = ['60', '1201', '30', '17', '900']
>>> a_set = set(a)
>>> b_set = set(b)
>>> [*filter(lambda x: x in b_set, a), *filter(lambda x: x not in a_set, b)]
['30', '17', '60', '1201', '900']
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢理解:

>>> [*(x for x in a if x in b_set), *(x for x in b if x not in a_set)]
['30', '17', '60', '1201', '900']
Run Code Online (Sandbox Code Playgroud)

两者都需要线性时间,这比排序要好。