Python
Programming
Data Structures
List Management
Coding Tips

Only Add Unique Item To List

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want to add an item to a Python list only when it is not already present, the simplest solution is a membership check before append. That works well for small lists, but once the collection grows or uniqueness becomes a core requirement, it is worth choosing a data structure that matches the rule more directly.

The Simple List Check

For many scripts, this is enough:

python
1items = ["red", "green"]
2candidate = "blue"
3
4if candidate not in items:
5    items.append(candidate)
6
7print(items)

This preserves list order and keeps the code easy to read. The tradeoff is performance. candidate not in items scans the list linearly, so each check is O(n).

That is perfectly acceptable when:

  • the list is small
  • inserts are infrequent
  • readability matters more than optimization

Use a Set When Fast Uniqueness Matters

If uniqueness checks happen often, a set is usually the better primary structure because membership is average-case O(1).

python
1seen = {"red", "green"}
2
3for candidate in ["green", "blue", "blue", "yellow"]:
4    if candidate not in seen:
5        seen.add(candidate)
6
7print(seen)

The downside is that sets are unordered in the general conceptual sense, even though current Python implementations preserve insertion order as an implementation detail for dictionaries, not as a list replacement contract for all use cases. If presentation order matters, use a combined pattern.

Preserve Order with a List and a Set

One common approach is to store ordered values in a list and store membership in a companion set.

python
1items = []
2seen = set()
3
4for candidate in ["red", "green", "red", "blue"]:
5    if candidate not in seen:
6        items.append(candidate)
7        seen.add(candidate)
8
9print(items)

This gives you:

  • fast uniqueness checks
  • stable insertion order
  • explicit control over output

It is a strong default when you are building menus, tags, or deduplicated event streams.

Handling Unhashable Items

Sets only work with hashable values. Lists, dictionaries, and other mutable objects cannot be added directly to a set. In that case, derive a stable key from the item.

python
1records = []
2seen_ids = set()
3
4incoming = [
5    {"id": 1, "name": "Ana"},
6    {"id": 2, "name": "Bo"},
7    {"id": 1, "name": "Ana again"},
8]
9
10for record in incoming:
11    key = record["id"]
12    if key not in seen_ids:
13        records.append(record)
14        seen_ids.add(key)
15
16print(records)

Here, uniqueness is based on id, not on the entire dictionary object. That is usually what you actually mean in application code.

Wrap the Pattern in a Helper

If you do this often, a helper function keeps the call site tidy:

python
1def append_unique(items, item):
2    if item not in items:
3        items.append(item)
4        return True
5    return False
6
7
8colors = ["red", "green"]
9print(append_unique(colors, "green"))
10print(append_unique(colors, "blue"))
11print(colors)

For higher-throughput code, write a helper that manages both a list and a set together instead of repeating the bookkeeping across the codebase.

When a List Is the Wrong Structure

Sometimes the real answer is not “make the list smarter” but “stop using a list for uniqueness.” If the collection is fundamentally a set of unique values, model it as a set first and convert to a list only when you need sequence behavior.

That tends to reduce bugs because the data structure itself enforces the rule instead of relying on every caller to remember an if statement.

Common Pitfalls

The most common mistake is repeatedly using if item not in items on a large list inside a loop. It works, but performance degrades as the list grows because every membership test scans from the beginning.

Another issue is assuming a set is a drop-in replacement for a list. Sets remove duplicates quickly, but they do not support indexing and are not the right choice if your downstream code depends on sequence operations.

For object-like records, developers also often compare the whole object when they really need a business key such as id or email. That leads to accidental duplicates that look different in memory but represent the same entity.

Finally, be explicit about whether you want to keep the first occurrence or replace it with a later one. “Unique” does not answer that policy question by itself.

Summary

  • For small lists, if item not in items before append is fine.
  • For frequent checks, a set gives much faster membership tests.
  • Use a list plus a set when you need both order and uniqueness.
  • For unhashable records, deduplicate by a stable key.
  • Pick the data structure that enforces the rule you actually need.

Course illustration
Course illustration

All Rights Reserved.