简体   繁体   中英

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 ).

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

The desired output is [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.

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 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 ).

You could use numpy array , and the function 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) .

Membership tests take O(n) time for lists and O(1) time for sets . Using a set would reduce the time complexity of the required code to O(n) , which would have otherwise been 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

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

(borrowing naming convention from numpy )

which will be much faster when the lists get large (ie more than a few hundred elements each)

using lambda

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

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

print(res)

output

[False, True, True]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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