Distinct values with a set comprehension
A set comprehension collects the distinct values a collection contains. Repeats disappear, and so does the order.
- Build a set of distinct values with
{expression for item in items} - Compare two sets with
differenceandunionto answer who-is-missing questions - Sort a set when you need to show it, because a set has no order and no positions
*Which countries do our users come from?* is not *list every user's country*: you want each country once. In the Collection Algorithms module you skipped values already seen. A set does that by itself: it holds each value at most once.
A set comprehension uses braces without a colon: {expression for item in items}. A set has no order, so when you print it for people, sort it first with sorted, which gives a list.
Run each example to see what it prints. Running examples doesn't count toward progress.
users = [
{"user_id": 6078, "country": "Canada"},
{"user_id": 7345, "country": "Brazil"},
{"user_id": 7712, "country": "Canada"},
{"user_id": 8020, "country": "India"},
]
countries = {user["country"] for user in users}
print(len(countries))
print(sorted(countries))Because a set has no order, it has no positions either. Asking for the first item is an error, not the first country you added.
countries = {"Canada", "Brazil", "India"}
print(countries[0])Sets earn their keep when you compare two collections. Build a set from each, then let difference (see Dictionaries & Sets) answer *who is in the first but not the second*. Checking in against a set is also fast however large it gets, which matters when you check thousands of IDs.
def never_rated(users, ratings): everyone = {user["user_id"] for user in users} raters = {rating["user_id"] for rating in ratings} return everyone.difference(raters) users = [{"user_id": 6078}, {"user_id": 7345}, {"user_id": 7712}, {"user_id": 8020}] ratings = [ {"user_id": 6078, "movie_id": 2439}, {"user_id": 6078, "movie_id": 935}, {"user_id": 8020, "movie_id": 266}, ] print(sorted(never_rated(users, ratings)))
When to use it: distinct values (countries, tags, airports), and *in A but not B* questions. Mistakes to avoid: expecting the set to keep the order you added things in; indexing a set; and writing {} for an empty set. Empty braces make an empty dictionary; an empty set is written set().
{expression for item in items}keeps each value once. Normalise first if different spellings should count as one.- A set has no order and no positions: sort it to show it, and use
differenceorunionto compare. {}is an empty dictionary; an empty set isset().- Next: two
forclauses in one comprehension, to flatten lists inside lists.