如何检查列表中每个元素的 Python 是否包含在另一个列表中?

How to check in Python for each element of a list, whether it is contained in another list?

在 Python 中如何检查列表的每个元素(比如 l1),是否包含在另一个列表中(比如 l2)。

l1 = ['a', 'b', 'c']
l2 = ['b', 'c']

所需的输出是 [False, True, True]。所以我真的想要一个 len(l1) 的布尔向量,而不是像 ['b', 'c'] 等的某种交集。我的问题与 this question 不同,因为我的问题不足以知道是否第一个列表中的 任何 元素包含在第二个列表中,但是 哪些 元素是,哪些不是。

使用 list comprehension:

[x in l2 for x in l1]

解释:

  • 我发现最好理解的是,从 for x in l1 部分开始时:创建一个临时变量 x 并循环 l1 中的所有元素,类似于 [=21] =].
  • 现在检查每个 x 是否在 l2 中(因此 x in l2 中的 ininx in l1).

这个也行

l1 = ['a', 'b', 'c']
l2 = ['b', 'c']

result = []
for i in l1 : 
  result.append(i in l2)

但是很长

您可以使用 numpy array 和函数 numpy.in1d:

import numpy

l1 = ['a', 'b', 'c']
l2 = ['b', 'c']
results = numpy.in1d(l1, l2)

检查一个元素是否在列表中需要 O(n) 操作,如果你重复多次,那么使用 set 是值得的,它具有(摊销)O(1) 的成员测试,给你

def in1d(l1, l2):
  s2 = set(l2)
  return [x in s2 for x in l1]

(借用 numpy 的命名约定)

当列表变大时(即每个元素超过几百个),这会更快

如果有两个列表,l1l2,我们必须检查l1的每个元素是否存在于l2中,最好转换l2set 并检查 l1 的每个元素在 set(l2).

中的成员资格

lists 成员资格测试需要 O(n) 时间,sets 成员资格测试需要 O(1) 时间。使用 set 会将所需代码的时间复杂度降低到 O(n),否则会是 O(n<sup>2</sup>).

l1 = ['a', 'b', 'c']
l2 = ['b', 'c']

# Converting to a set takes O(n) time
s2 = set(l2)  # {'c', 'b'}


# Each of the following approaches takes O(n) time

# Normal approach
contains_n = []
for x in l1:
    contains_n.append(x in s2)


# Using a list comprehension
contains_lc = [
    x in s2
    for x in l1
]


# Using a functional approach
contains_f = list(map(lambda x: x in s2, l1))


print(f'contains_n: {contains_n}')
print(f'contains_lc: {contains_lc}')
print(f'contains_f: {contains_f}')

输出:

contains_n: [False, True, True]
contains_lc: [False, True, True]
contains_f: [False, True, True]

使用 lambda

l1 = ['a', 'b', 'c']
l2 = ['b', 'c']

res = list(map(lambda x: x in l2, l1))

print(res)

输出

[False, True, True]