简体   繁体   English

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

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

How does it work in Python to check for each element of a list (say l1 ), whether it is contained in another list (say l2 ).它如何在 Python 中检查列表的每个元素(比如l1 ),它是否包含在另一个列表中(比如l2 )。

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

The desired output is [False, True, True] .所需的输出是[False, True, True] So I really want a boolean vector of len(l1) and not some kind of intersection like ['b', 'c'] etc. My questions differs from this question in the sense that it is not sufficient for my problem to know whether there any element from the first list contained in the second, but which elements are, and which are not.所以我真的想要一个len(l1)的布尔向量,而不是像['b', 'c']等的某种交集。我的问题与这个问题不同,因为我的问题不知道是否足够第二个列表中包含第一个列表中的任何元素,但哪些元素是,哪些不是。

Use a list comprehension :使用列表理解

[x in l2 for x in l1]

Explanation:解释:

  • I find it to be understood best, when starting with the for x in l1 part: a temporary variable x is created and looped all elements in l1 similar to a for loop .我发现它最好理解,当从for x in l1部分的for x in l1开始时:创建一个临时变量x并循环l1所有元素,类似于for 循环
  • for each of this x it is now checked, whether it is in l2 (so the in in x in l2 has a different meaning than the in in x in l1 ).对于每个这样的x它现在检查中,无论是在l2 (所以inx in l2具有不同的含义比inx in l1 )。

You could use numpy array , and the function numpy.in1d :您可以使用numpy array和函数numpy.in1d

import numpy

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

If there are two lists, l1 and l2 , and we have to check if each element of l1 is present in l2 , it's better to convert l2 to a set and check for membership of each element of l1 in set(l2) .如果有两个列表, l1l2 ,并且我们必须检查l1每个元素是否存在于l2 ,最好将l2转换为一个set并检查l1的每个元素在set(l2)成员资格。

Membership tests take O(n) time for lists and O(1) time for sets .成员资格测试对lists花费O(n)时间,对sets花费O(1)时间。 Using a set would reduce the time complexity of the required code to O(n) , which would have otherwise been O(n 2 ) .使用set会将所需代码的时间复杂度降低到O(n) ,否则将是O(n 2 )

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}')

Output:输出:

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

this works too这也有效

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

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

but it's long但它很长

checking whether an element is in a list takes O(n) operations, if you're repeating this many times it's worth using a set which has membership tests of (amortised) O(1), giving you检查一个元素是否在列表中需要 O(n) 次操作,如果你重复这么多次,那么值得使用一个具有(摊销)O(1) 的成员资格测试的set ,给你

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

(borrowing naming convention from numpy ) (从numpy借用命名约定)

which will be much faster when the lists get large (ie more than a few hundred elements each)当列表变大时(即每个列表超过几百个元素),这会快得多

using lambda使用lambda

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

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

print(res)

output输出

[False, True, True]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM