1: When I hit the opening bracket, I don't know whether I'm looking at an array literal or a comprehension. I have to read ahead a few tokens to disambiguate.
2: When I hit `transform(bar)`, I don't know what `bar` is either. I have to jump forward to disambiguate again.
3: Once I hit `for bar in` I realize I'm in a comprehension, but that's still not enough to figure out what `transform(bar)` is acting on. I have to read to the end of the `if` condition, then backtrack to the beginning.
bonus reason: why not `list(baz)`? Is there actually some logic to when Python uses methods and when it uses global functions? If so, please tell me.
another bonus reason: when I was learning Python, I found the keyword reuse genuinely confusing. I would try to write for loops like `for x in my_list if condition(x):` and couldn't figure out why it didn't work because I knew I had seen that syntax somewhere before.
Now, your particular example isn't that bad, but if you make it just a little more complicated you get something like this aberration:
foo = [transform(bar) if bar.property else bar for bar in baz.list() if condition(bar)]
Nothing will convince me that you're not a mutant if you think that's clear and concise.
Meanwhile, over in Ruby-land, we write this:
baz.each.select{ |bar|
condition(bar)
}.map{ |bar|
bar.property ? transform(bar) : bar
}
Which to me parses very easily into meat-brain logic, in small chunks, with a single pass:
-Start with `baz`
-Consider each item
-Select only those `bar`s that meet `condition`
-Map each `bar` to...
-`transform(bar)` when `property` is true; itself otherwise (okay, natural language actually more closely resembles Python-style ternaries here. Sue me).
P.S. apologies for the multiple edits; I am an HN formatting noob.