How do I remove duplicates from a list while keeping the order?
Short answer
Use dict.fromkeys to drop duplicates while preserving first-seen order. Converting to a set removes duplicates too but loses order, which is the common mistake.
The short version
Use list(dict.fromkeys(items)). It keeps the first occurrence of each value and drops later repeats, preserving the original order. Converting to a set also removes duplicates but does not guarantee order, which is why it is the wrong tool when order matters.
The order-preserving way
items = [3, 1, 3, 2, 1]
unique = list(dict.fromkeys(items))
print(unique) # [3, 1, 2]
dict.fromkeys builds a dictionary using the items as keys. Dictionaries keep insertion order (since Python 3.7) and cannot have duplicate keys, so repeats are dropped automatically and the first-seen order survives.
The tempting mistake
unique = list(set(items))
print(unique) # order not guaranteed, e.g. [1, 2, 3]
A set removes duplicates, but sets are unordered, so the result can come back in any order. If you only care about which values are present, this is fine and fast. If you care about the order they first appeared, it is wrong.
When the items are not hashable
Both methods above need the items to be hashable, which rules out lists and dictionaries as elements. For a list of lists, fall back to a manual pass with a "seen" set of a hashable form.
seen = set()
unique = []
for row in [[1, 2], [1, 2], [3, 4]]:
key = tuple(row) # a hashable version
if key not in seen:
seen.add(key)
unique.append(row)
print(unique) # [[1, 2], [3, 4]]
Why not just loop and check the result list
You may be tempted to write if x not in unique. That works but is slow, because not in on a list scans it every time, making the whole thing quadratic. The seen set makes each check fast, so the loop stays efficient even on large inputs. For simple hashable items, dict.fromkeys gives you all of this in one readable line, so reach for it first.