Python comprehensions are often described as “more readable” when they are introduced to learners. Learners are commonly baffled by this. I was, and I’ve seen others push back at this description as well. Consider two trivial code examples. First without a comprehension:
numbers = [1, 2, 3, 4, 5, 6]even_numbers = []for number in numbers: if number % 2 == 0: even_numbers.append(number)
The intention is clear, and the way the code fulfills that intention is clear. The order of the operations follows the same simple, almost naive way most people, even non-programmers, would approach the problem of “collect the even numbers from this list into another list”:
- Select one number from the first list
- Check if it’s an even number
- If it is, add it to the new list
- If it’s not, do nothing and continue with the next number in the first list
Now consider an example that uses a list comprehension:
numbers = [1, 2, 3, 4, 5, 6]even_numbers = [number for number in numbers if number % 2 == 0]
The intention is carried almost entirely by the variable name even_numbers . But in the mind of a reader who is not familiar with comprehensions, the expectation created by that variable name is not quite fulfilled by the code that follows, for a couple of reasons:
- Having long expressions between square brackets is an unfamiliar use of square brackets. The brain has to pause to try to figure out what it means.
- Seeing variables or expressions before a
forstatement is a similarly weird thing. There’s almost no other situation in whichforis not the first thing on a line. The brain has to pause to figure out if this is some sort of overloading, or howexpressionfordiffers from regularfor. They may not figure it out.
Overall, the code doesn’t read like the almost prose-style code in the first example.
Recently, I watched a PyCon talk where the speaker talked a bit about comprehensions. Someone in the audience asked a question challenging the speaker’s assertion that comprehensions are readable. Listening to their interaction, I felt agreement with both their points of view. I think of comprehensions as very readable and Pythonic, but I also agreed with the audience member’s position that they were not readable.
In thinking about this contradiction, I came to the conclusion that both of them are right, because readability is not inherent to the comprehension syntax. Instead, readability is observer relative.
Natural language similarities
To illustrate this, we can step away from programming languages temporarily, and consider natural languages. French has an interesting numbering system to a natively anglophone mind. Consider the number 97 for example. The way we say this word in English is very straightforward, to our minds. Ninety-seven. Ninety, then seven.
But in French? It’s quatre-vingt-dix-sept. Literally translated, that means four-twenty ten-seven. As in, four times twenty plus ten plus seven.
For most anglophone people who learn French, this is an overly complex numbering system, and we struggle with it; I certainly did at first. But over time, and with more and more exposure, it becomes normalized in our minds. We stop translating or doing mental math, and just take the language for what it is. Eventually, we even stop noticing it. It just rolls off our tongue. Quatre-vingt-dix-sept.
But it doesn’t end there. Many anglophone people who learn French learn the variety that is spoken in France. After some time, we start to get exposure to other varieties of French. One of the things we learn is that in certain parts of the francophone world, like some parts of Switzerland, they wouldn’t say quatre-vingt-dix-sept. They’d say nonante-sept.
Nonante-sept. Literally ninety-seven.
Nonante-sept! Quelle horreur! Much gasping and pearl clutching follows. Why do they do that? Who does that? That’s just weird and wrong!
But nonante-sept is almost identical to what an anglophone mind knows. If we had learned nonante-sept from the start, we wouldn’t have struggled with the numbering system nearly as much. So why do we have a negative reaction when we learn about it years later? Because through repeated exposure, quatre-vingt-dix-sept has become normalised, so much so that the thing that would have been “normal” now seems unusual.
This is exactly what Python comprehensions are (and so many other things in life, by the way). Whether or not they’re “readable” is not inherent in them. Instead, it’s a matter of how much exposure the reader has had to them.
Making the unreadable readable
The work of learning, with comprehensions or pretty much anything else, is therefore:
- Accepting that things will look weird at the start of the learning process, whether we’re learning a programming language or a natural language
- Getting continued, repeated exposure to the thing being learned
- Giving oneself time, because given enough time, even the strangest things will become familiar, i.e. readable, and the difference between people who consider comprehensions readable and those who don’t, is probably just exposure.
Happy learning!