Explain Codes LogoExplain Codes Logo

How to Check if One of the Following Items Is in a List?

python
sets
any
generator-expressions
Nikita BarsukovbyNikita Barsukov·Aug 10, 2024
TLDR

Easily find if an item exists in a list using Python's any() function alongside a generator:

items, targets = ['apple', 'banana', 'cherry'], {'banana', 'mango'} found = any(i in items for i in targets)

found will be True if any target is found within items.

Couple of methods to check items in a list

Checking with sets for speed gains

When dealing with large datasets, converting a list to a set can be faster due to the constant time complexity for lookup operations in sets:

large_items = set(['apple', 'banana', 'cherry']) # Imagine this is a very, very long list targets = {'banana', 'mango'} found = not targets.isdisjoint(large_items) # Speedy Gonzalez, eh?

Dangers of multiple item checks with the 'or' operator

Avoid using 'or' for conducting multiple item checks, as it can lead to false positives. 'Or' resolves to True when just one condition is satisfied:

items = ['apple', 'banana', 'cherry'] # Misleading usage of 'or' found = 'banana' in items or 'mango' in items # This says True, though there is no 'mango', sneaky!

The drawback of list comprehensions for checks

List comprehensions are wonderful constructs, but using them for checking item presence may lead to scanning the entire list even after a match is found. Here, generators and any() come to our rescue:

items = ['apple', 'banana', 'cherry'] targets = ['banana', 'mango'] found = any([i in items for i in targets]) # This creates an entire memory-eating list first!

Going deep into certain tricks and insights

Embrace the laziness of any with generator expressions

Generator expressions bring the concept of lazy evaluation to our code. They generate items one by one, potentially saving computational time:

items = ['apple', 'banana', 'cherry'] targets = {'banana', 'mango'} # The lazy way isn't always the wrong way! found = any(i in items for i in targets)

False alarm on empty collections in Python

Remember, in Python, empty collections e.g., sets or lists evaluate to False:

# An empty can isn't very useful, is it? found = bool({'banana', 'mango'}.intersection(items))

Sets are your best friend for repetitive checks

If you find yourself checking for the same items repeatedly, especially in a loop, do consider converting your list to a set first. Sets are more efficient at checking memberships:

# If you're lost in a sea of repetition, cling on to sets. items_set = set(items) targets = ['banana', 'mango'] found = any(i in items_set for i in targets)

Key takeaway reminders

  • any() paired with generators is your best friend for efficiency.
  • Convert your lists to sets when working with large frequently accessed datasets.
  • Don't forget the meaning of truth in Python collections, empty is False.
  • When in doubt, let Python be lazy (with generator expressions).