Python
list
search
duplicate
coding-tips

Python finding an element in a list

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Python provides several ways to find elements in a list: the in operator for existence checks, list.index() for finding positions, list.count() for counting occurrences, list comprehensions for filtering multiple matches, and the filter() function for functional-style searching. For large datasets where frequent lookups are needed, converting to a set or dict provides O(1) lookups instead of O(n) linear scans.

Check Existence with in

The in operator returns True if the element exists anywhere in the list:

python
1fruits = ['apple', 'banana', 'cherry', 'date', 'banana']
2
3print('banana' in fruits)   # True
4print('grape' in fruits)    # False
5print('banana' not in fruits)  # False
6
7# Use in conditional logic
8if 'cherry' in fruits:
9    print("Found cherry!")

The in operator performs a linear scan — it checks each element from left to right until it finds a match or reaches the end. Time complexity is O(n).

Find Index with list.index()

list.index(value) returns the index of the first occurrence. It raises ValueError if the element is not found:

python
1colors = ['red', 'green', 'blue', 'green', 'yellow']
2
3print(colors.index('blue'))    # 2
4print(colors.index('green'))   # 1 (first occurrence only)
5
6# Search within a range: index(value, start, stop)
7print(colors.index('green', 2))  # 3 (search starts at index 2)
8
9# Safe lookup — avoid ValueError
10def safe_index(lst, value):
11    try:
12        return lst.index(value)
13    except ValueError:
14        return -1
15
16print(safe_index(colors, 'purple'))  # -1

Find All Indices

python
1numbers = [10, 20, 30, 20, 40, 20, 50]
2
3# List comprehension to find all indices of 20
4indices = [i for i, x in enumerate(numbers) if x == 20]
5print(indices)  # [1, 3, 5]
6
7# Using a generator for memory efficiency with large lists
8def find_all(lst, value):
9    return (i for i, x in enumerate(lst) if x == value)
10
11for idx in find_all(numbers, 20):
12    print(idx)  # 1, 3, 5

Count Occurrences with list.count()

python
1data = [1, 2, 3, 2, 4, 2, 5]
2
3print(data.count(2))  # 3
4print(data.count(9))  # 0
5
6# Check if element exists using count
7if data.count(2) > 0:
8    print("Found at least one 2")

Note that list.count() always scans the entire list. For simple existence checks, in is more efficient because it stops at the first match.

Filter with List Comprehension

List comprehensions are the most Pythonic way to find elements matching a condition:

python
1people = [
2    {'name': 'Alice', 'age': 30},
3    {'name': 'Bob', 'age': 25},
4    {'name': 'Charlie', 'age': 35},
5    {'name': 'Diana', 'age': 28},
6]
7
8# Find people over 28
9older = [p for p in people if p['age'] > 28]
10print(older)
11# [{'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
12
13# Find names starting with a specific letter
14b_names = [p['name'] for p in people if p['name'].startswith('B')]
15print(b_names)  # ['Bob']

Find First Match with next()

To get only the first matching element without scanning the entire list:

python
1people = [
2    {'name': 'Alice', 'age': 30},
3    {'name': 'Bob', 'age': 25},
4    {'name': 'Charlie', 'age': 35},
5]
6
7# Find first person over 28 (stops at first match)
8first = next((p for p in people if p['age'] > 28), None)
9print(first)  # {'name': 'Alice', 'age': 30}
10
11# Default value if no match found
12missing = next((p for p in people if p['age'] > 50), None)
13print(missing)  # None

The generator expression with next() is efficient because it stops iterating as soon as it finds the first match.

Using filter()

The filter() function applies a function to each element and returns an iterator of matches:

python
1numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2
3# Find even numbers
4evens = list(filter(lambda x: x % 2 == 0, numbers))
5print(evens)  # [2, 4, 6, 8, 10]
6
7# filter returns an iterator — convert to list to see all results
8# Or iterate directly
9for n in filter(lambda x: x > 7, numbers):
10    print(n)  # 8, 9, 10

Performance: set and dict for Frequent Lookups

Lists have O(n) lookup time. For repeated membership checks, convert to a set for O(1) average-case lookups:

python
1# Slow — O(n) per lookup, O(n*m) total
2allowed_ids = [101, 202, 303, 404, 505]  # ... thousands of IDs
3requests = [101, 999, 303, 888, 505]
4
5# Linear search: O(n) per check
6for req in requests:
7    if req in allowed_ids:  # O(n) each time
8        print(f"{req} is allowed")
9
10# Fast — O(1) per lookup, O(n+m) total
11allowed_set = set(allowed_ids)  # One-time O(n) conversion
12
13for req in requests:
14    if req in allowed_set:  # O(1) each time
15        print(f"{req} is allowed")
python
1# dict for value-based lookups
2users = [
3    {'id': 1, 'name': 'Alice'},
4    {'id': 2, 'name': 'Bob'},
5    {'id': 3, 'name': 'Charlie'},
6]
7
8# Build a lookup dict — O(n) once
9users_by_id = {u['id']: u for u in users}
10
11# O(1) lookups
12print(users_by_id.get(2))   # {'id': 2, 'name': 'Bob'}
13print(users_by_id.get(99))  # None

Common Pitfalls

  • Using list.index() without checking existence first: index() raises ValueError if the element is not in the list. Either use a try/except block or check with in before calling index().
  • Using list.count() for existence checks: count() scans the entire list even if the element is found early. Use in for simple existence checks, which stops at the first match.
  • Repeated in checks on large lists: Each in check is O(n). If you need to check membership thousands of times, convert the list to a set first for O(1) lookups.
  • Modifying a list while iterating over it: Removing elements during iteration skips elements or raises errors. Iterate over a copy (for x in list(original)) or use list comprehension to build a new list.
  • Comparing objects without __eq__: Custom objects use identity comparison (is) by default. Define __eq__ on your class so that in and index() compare by value instead of by object identity.

Summary

  • Use in for simple existence checks (stops at first match, O(n))
  • Use list.index() to find the position of an element (raises ValueError if missing)
  • Use list comprehensions to find all matching elements or their indices
  • Use next() with a generator expression to efficiently find the first match
  • Convert to set or dict for O(1) lookups when checking membership repeatedly

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.