How to Convert a List to a Set in Python

To convert a list to a set in Python, pass it to set(): set(["Austin", "Denver", "Austin"]) returns {'Austin', 'Denver'}. Duplicates disappear and the order isn’t kept, but checking membership with in becomes much faster:

cities = set(visits)
"Boston" in cities   # fast lookup

The examples deal with city visits, customer emails and ZIP codes, run on Python 3.12.5; the set printouts may list items in a different order on your machine.

You’ll see set() and its traps, converting with a transform, unhashable items and frozenset, comparing two lists, and how much faster set lookups are.

Convert a list to a set with set()

set() takes any iterable. That’s handy for lists but surprising for strings, and remember that {} creates a dict, not a set:

visits = ["Austin", "Denver", "Austin", "Boston", "Denver", "Austin"]

cities = set(visits)
print(cities, type(cities).__name__, len(cities))
print("Boston" in cities)

print(set("Austin"))         # a string is iterable: you get its characters
print({"Austin"})            # a set literal with one string
print(type({}).__name__, type(set()).__name__)   # {} is an empty dict, not a set

Output:

{'Denver', 'Boston', 'Austin'} set 3
True
{'t', 's', 'A', 'i', 'u', 'n'}
{'Austin'}
dict set
Command Prompt output of Python converting a list of city visits to a set, plus set of a string versus a one-item set literal
Six visits become three cities, set(“Austin”) splits into letters, {“Austin”} keeps the word, and {} turns out to be a dict.

I always write set() for an empty set; more on that in creating an empty set in Python.

Convert a list to a set while cleaning the values

A set comprehension lets you normalize values on the way in, so near-duplicates collapse too:

emails = ["Emily@Example.com", "emily@example.com ", "JAMES@example.com", "olivia@example.com"]

unique_emails = {e.strip().lower() for e in emails}
print(sorted(unique_emails))

prices = [19.99, 5.25, 19.99, 102.0, 5.25]
print(sorted({round(p) for p in prices}))

Output:

['emily@example.com', 'james@example.com', 'olivia@example.com']
[5, 20, 102]

Four email strings become three addresses once case and spaces are fixed. I run every mailing list through this before importing it. To keep the first-seen order instead, see getting unique values from a list.

Why do I get TypeError: unhashable type ‘list’?

Set items must be hashable, and lists can change, so they aren’t. Convert inner lists to tuples, and use frozenset when the items are themselves sets:

pairs = [["TX", "Austin"], ["CO", "Denver"], ["TX", "Austin"]]

try:
    set(pairs)
except TypeError as err:
    print("TypeError:", err)

print(set(map(tuple, pairs)))

tags = [frozenset({"sale", "new"}), frozenset({"new", "sale"}), frozenset({"clearance"})]
print(set(tags), "<- frozensets are hashable, and order inside them doesn't matter")

Output:

TypeError: unhashable type: 'list'
{('CO', 'Denver'), ('TX', 'Austin')}
{frozenset({'clearance'}), frozenset({'sale', 'new'})} <- frozensets are hashable, and order inside them doesn't matter
Command Prompt output of Python TypeError unhashable type list when converting a list of lists to a set, fixed with tuples and frozenset
set() on the pairs fails, the tuple version keeps two distinct pairs, and the two frozensets with the same tags count as one.

Tuples are hashable as long as everything inside them is. The differences between the two types are in Python set vs tuple.

Compare two lists by converting them to sets

Once both lists are sets, the operators answer the usual questions directly: in both, in either, in one but not the other:

monday = ["emily", "james", "olivia", "liam", "emily"]
tuesday = ["james", "ava", "liam", "noah"]

a, b = set(monday), set(tuesday)
print("both days:   ", sorted(a & b))
print("either day:  ", sorted(a | b))
print("Monday only: ", sorted(a - b))
print("one day only:", sorted(a ^ b))
print("all of Tuesday came Monday?", b <= a)

Output:

both days:    ['james', 'liam']
either day:   ['ava', 'emily', 'james', 'liam', 'noah', 'olivia']
Monday only:  ['emily', 'olivia']
one day only: ['ava', 'emily', 'noah', 'olivia']
all of Tuesday came Monday? False
Command Prompt output of Python set intersection, union, difference and symmetric difference on two days of visitor lists
james and liam came both days, six people came on either day, emily and olivia only Monday, and not all of Tuesday’s visitors came Monday.

<= tests for a subset. Adding to a set afterwards is covered in adding items to a set in Python.

How much faster is a set than a list for lookups?

x in some_list checks items one by one. A set uses hashing, so the lookup doesn’t depend on its size. Here’s a ZIP code near the end of 100,000:

import timeit

zips = [str(10000 + i) for i in range(100_000)]
zip_set = set(zips)
look_for = "109999"                        # near the end of the list

t_list = min(timeit.repeat(lambda: look_for in zips, number=200, repeat=3))
t_set = min(timeit.repeat(lambda: look_for in zip_set, number=200, repeat=3))
print(f"list: {t_list * 1000:8.2f} ms for 200 lookups")
print(f"set:  {t_set * 1000:8.4f} ms for 200 lookups")
print("set faster:", t_set < t_list)

Output:

list:    85.26 ms for 200 lookups
set:    0.0070 ms for 200 lookups
set faster: True
Command Prompt timing Python membership tests for a ZIP code in a 100,000 item list versus a set
The list takes milliseconds for 200 lookups while the set takes a tiny fraction of that, and the final line confirms the set is faster.

Your exact timings will vary, but the gap grows with the list. To go back to a list for sorting or indexing, see converting a set to a list.

List to set conversion quick reference

GoalCode
Basic conversionset(lst)
Clean values on the way{x.strip().lower() for x in lst}
List of listsset(map(tuple, lst))
Hashable set (dict key)frozenset(lst)
In both listsset(a) & set(b)
Empty setset(), not {}

For more on sets, read these next:

Frequently asked questions

How do I convert a list to a set in Python?

Use set(my_list). Duplicates are removed and order isn’t kept.

Does converting a list to a set keep the order?

No. Use list(dict.fromkeys(my_list)) if you need unique values in order.

Why does set(“Austin”) give letters?

A string is an iterable of characters. Use {"Austin"} or set(["Austin"]).

Why can’t I convert a list of lists to a set?

Lists are unhashable. Convert each inner list to a tuple first.

Is a set faster than a list?

For in checks, yes: set lookups don’t slow down as the collection grows.

Where are sets documented?

See set and frozenset in the Python docs.