Python
ordered set
data structures
programming
sets

Does Python have an ordered set?

Master System Design with Codemia

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

Introduction

Python does not have a built-in OrderedSet type in the standard library. However, since dictionaries preserve insertion order in modern Python, you can get most ordered-set behavior by storing keys in a dict and ignoring the values.

What An Ordered Set Means

A normal set gives you uniqueness but not a guaranteed insertion order interface. An ordered set usually means:

  • Elements stay unique.
  • Iteration follows insertion order.
  • Membership tests stay fast.

Python's regular set handles the first and third points well, but not the second in a way you should rely on for program semantics.

The Simplest Practical Replacement

For many cases, dict.fromkeys is enough:

python
1items = ["a", "b", "a", "c", "b"]
2ordered_unique = list(dict.fromkeys(items))
3
4print(ordered_unique)  # ['a', 'b', 'c']

This is the most common answer when the real goal is "remove duplicates but keep order."

If you want a reusable ordered set object, store elements as dictionary keys:

python
1class OrderedSet:
2    def __init__(self, iterable=()):
3        self._data = dict.fromkeys(iterable)
4
5    def add(self, item):
6        self._data[item] = None
7
8    def discard(self, item):
9        self._data.pop(item, None)
10
11    def __contains__(self, item):
12        return item in self._data
13
14    def __iter__(self):
15        return iter(self._data)
16
17    def __len__(self):
18        return len(self._data)
19
20    def __repr__(self):
21        return f"OrderedSet({list(self._data)})"
22
23
24s = OrderedSet(["x", "y", "x"])
25s.add("z")
26print(s)
27print("y" in s)

That gives you insertion order plus uniqueness with very little code.

Why A Dictionary Works

From Python 3.7 onward, insertion order is a language guarantee for dictionaries. In CPython 3.6, it was already true as an implementation detail, but 3.7 is the version where you can rely on it portably.

Because dictionary keys are unique, the structure naturally behaves like an ordered set. The values are irrelevant, so a placeholder such as None is enough.

When A Real set Is Still Better

If you only care about uniqueness and fast membership and do not need stable iteration order, use a regular set:

python
seen = set()
seen.add("a")
seen.add("b")

The standard set API is richer and communicates intent better when ordering does not matter.

Ordered Deduplication In Practice

A common use case is preserving the first occurrence of items:

python
1def unique_in_order(values):
2    return list(dict.fromkeys(values))
3
4
5print(unique_in_order([3, 1, 3, 2, 1, 4]))

This is often simpler than introducing a full ordered-set abstraction, especially in data-cleaning code.

Limits Of The dict-Based Pattern

The dict-based approach gives insertion order, but it is not a full standard-library ordered-set type with every method you might expect. If you need set algebra such as union, intersection, and difference while preserving order, you either implement those methods yourself or use a dedicated third-party package.

For example, an ordered union can be written like this:

python
1def ordered_union(left, right):
2    result = OrderedSet(left)
3    for item in right:
4        result.add(item)
5    return result
6
7
8print(ordered_union(["a", "b"], ["b", "c", "d"]))

That is easy enough for simple applications, but if ordered-set operations are central to your program, a dedicated implementation may be worth it.

Common Pitfalls

The biggest mistake is assuming set preserves insertion order just because it appears stable in one run. That behavior is not the contract you should build logic around.

Another common issue is overengineering the problem. If all you need is ordered deduplication, list(dict.fromkeys(values)) is usually enough.

Developers also sometimes forget that ordered-set elements still need to be hashable. A list or dictionary cannot become a key in the backing dictionary unless you convert it into a hashable form first.

Finally, be clear about your Python version. Relying on dictionary insertion order makes sense in modern Python, but old-version portability may require more caution.

Summary

  • Python does not ship a built-in OrderedSet in the standard library.
  • Modern dictionaries preserve insertion order, which makes them a practical replacement.
  • 'list(dict.fromkeys(values)) is the simplest way to deduplicate while keeping order.'
  • A small wrapper around dict can provide an ordered-set-like API.
  • Use a regular set when ordering does not matter.

Course illustration
Course illustration

All Rights Reserved.