Super sets

Super sets

I love sets.

Of the four main Python collection types - the others being dict, list and tuple - sets are under-appreciated and under-used. They're more efficient than lists, when you don't need to preserve order or have dupes. And personally, I find it easier to reason about algorithms that use them.

But I have a more interesting story today, with code:

Yesterday I was writing a script that works with customer email addresses. So my program stores those in memory, as a set of strings.

But first I have to load them from a text file: one email address per line. And while I'm at it, skip the blank lines.

One way to do this: have a function that takes the file path as an argument, and returns a set - the set of email address strings.

That's not what I did. Instead, I did this:

  1. class CustomerEmails(set):
  2. @classmethod
  3. def from_file(cls, path):
  4. with open(path) as handle:
  5. return cls(email for line in handle
  6. if (email := line.strip()) != '')

Use it like:

  1. emails = CustomerEmails.from_file('emails.txt')

Let's savor this:

  • This extends the built-in set, so it's a set. But it's semantically different from other sets, and has its own type name.
  • It's got a class method. Do you know about class methods? It's like a secondary constructor, sort of.
  • This class method loads the email addresses from the file, feeding each to the set constructor.
  • After stripping surrounding whitespace, and skipping blank lines.
  • Side note: the "return" line uses a generator comprehension.
  • And it does all this, and more, woven tightly together in a few lines.

Anywayz:

I wrote this class without even thinking about it. Just in the zone, coding, and thinking about how I needed to compose everything to solve the problem. A moment of concentration, and I suddenly banged it out, then moved on. Only later did I realize this little class brings together a lot of interesting ideas.

I think that's important to be able to do. It's one thing to learn about new features of the language, in isolation. But in real code, you don't use different language features in isolation, do you?

Nope. You moosh them all together. Pretty much on every line of code.

Something to think about as you continue growing in your craft.

But before you can moosh them, you first have to learn those tools and features of the language.

And as it turns out: the Powerful Python Newsletter will help you do just that.