10 Comments
Mar 17Liked by Stephen Gruppetta

This is great! Comprehensions can be confusing at first, but they come up quite often in Python.

One of the few drawbacks of formatters like black and ruff is how they handle comprehensions with conditionals. Here's how I've seen comprehensions formatted sometimes to make them more readable:

[

name

for name in names

if len(name) > 5

]

Both black and ruff collapse this into a single line. You can insert directives to skip reformatting on these lines, but that adds its own kind of clutter. Even if our comprehensions end up reformatted on a single line, knowing they can be broken up like this can help you make sense of them.

If you come across a comprehension you're struggling to make sense of, try writing it with the spacing that Stephen showed in this post, or breaking it up across lines. Even if a formatter undoes your work, your comprehension will remain. :)

Expand full comment
Mar 22Liked by Stephen Gruppetta

Finally! I understand why list comprehensions behave like that

Expand full comment
Mar 17Liked by Stephen Gruppetta

"Surely, this doesn't make sense, right? You have two options:

1. Accept it and memorise the two versions

2. Read on"

That's one helluva hook.

And thank you for vindicating my understanding of what a ternary operator actually is. I'd had a disagreement with someone recently who was insisting that conditional expression was the correct term an ternary operator was something specific to JavaScript.

Expand full comment

Great explanation as usual!

One way I like to visualize comprehensions is by thinking of the equivalent code using an explicit list (or dict).

In the standard way, you would do:

```

for name in names:

if name:

result.append(name)

```

The last part inside result.append is your expression, and the rest is unfolded in the same order.

```

for name in names:

results.append(name if name else "?")

```

No magic here, is just syntactic sugar reordering the good old for loop.

Expand full comment