More handy tools

INPUT · Slides

A container that keeps one of each

01 / 07

When you want the duplicates gone

Sometimes you want the repeats taken out of a list. Survey answers, the items on an order, the names of the people who turned up.

You can already write it. Set up an empty list and add only the things that are not in it yet.

But that is four lines for nothing more than "drop the duplicates".

numbers = [3, 1, 3, 2, 1]kinds = []for n in numbers:    if n not in kinds:        kinds.append(n)print(kinds)

Result

[3, 1, 2]

02 / 07

One word, set, and it is done

Python has a container called a set. Its defining feature is that it cannot hold the same value twice.

Hand a list to set(...) and back comes a set with the duplicates dropped. Those four lines are now one.

There is a reason sorted(...) is wrapped round it here. Two slides from now we come to it.

numbers = [3, 1, 3, 2, 1]print(sorted(set(numbers)))

Result

[1, 2, 3]

03 / 07

Writing one out in braces

You can also make a set by listing values inside { }, separated by commas. Braces with no colons in them are a set; with colons, it is a dictionary.

Write the same value twice and only one of it goes in, so colours below holds two things.

  • len(...) … how many are in there
  • in … whether a value is there

Those two you can use as they stand.

colours = {"red", "blue", "red"}print(len(colours))print("red" in colours)print("green" in colours)

Result

2
True
False

04 / 07

Never show one as it stands

This is the one thing to watch with sets. A set has no order.

It does not remember the order you put things in, and it does not keep them smallest first. So print it as it stands and the order you get out is not guaranteed to be the same every time. Looping over one directly with for is risky for the same reason.

When you want to show what is inside, put it in order through sorted(...) first, every time. sorted returns a list, which is why it comes out in square brackets.

colours = {"red", "blue", "yellow"}print(sorted(colours))

Result

['blue', 'red', 'yellow']

05 / 07

Putting in and taking out

A set can be changed after you have made it.

  • add(value) … put one in. Nothing happens if it is there already
  • discard(value) … take one out. No error if it was never there

Unlike a list and its append, add will not leave you with two of the same thing. No if needed to check "is this one in there yet".

colours = {"red", "blue"}colours.add("yellow")colours.add("red")print(len(colours))colours.discard("blue")print(sorted(colours))

Result

3
['red', 'yellow']

06 / 07

An empty set is set()

There is one awkward corner here, and it comes down to history.

{} is an empty dictionary, not an empty set. Dictionaries had already taken the braces.

When you want an empty set, write set(). This one you simply have to remember.

print(type({}))print(type(set()))

Result

<class 'dict'>
<class 'set'>

07 / 07

What a set is good at

To gather up what we have covered:

  • drop duplicates … set(xs)
  • how many kinds there are … len(set(xs))
  • whether something is in there … x in s

Showing things in order is not its strength, but when all you want to know is what is there, it is remarkably strong.

Next lesson we lay two sets over each other. Finding "the people on both lists" will no longer take a double loop.