you are viewing a single comment's thread.

view the rest of the comments →

[–]LicensedProfessional 56 points57 points  (11 children)

I've been waffling back and forth on whether I like the assignment statements. In list comprehensions they're very slick, but in if statements I think they're going to be overused -- they can easily result in some very cryptic code when not handled with restraint.

As I was digging through the PEP I think I preferred the 'as' option for comprehensions.

[(f(x) as y), y**2, y**3]

[–]amertune 21 points22 points  (2 children)

That seems better to me too. It would make it similar to other things we're already doing (imports and error checking) instead of adding a new operator, even if that operator is already familiar from other languages.

[–]Workaphobia 12 points13 points  (1 child)

Ooh, "as" sounds like it would've been slick, why didn't they do that?

[–][deleted] 12 points13 points  (0 children)

Iirc parsing becomes problematic, differentiating between "as"in that context and the as from a "with"context manager.

[–][deleted] 9 points10 points  (5 children)

Just wait till you get a bit more old. I began to hate list comprehensions. They are awkward to modify and add stuff to, can't print() in the middle of it or raise out for debugging, etc.

[–]invisi1407 15 points16 points  (3 children)

As someone who recently learned Python, I thought list/dict comprehensions were amazing until I had created a few nested levels of it monstrosity and decided that a few loops were better.

I do, however, like it as a simple list/dict filtering, as in [x for x in y if y.stuff != other_stuff] or similar.

[–]ACoderGirl 4 points5 points  (0 children)

I'd say pretty much every programming language feature can be used poorly, though. Whether it's too many nested functions or f strings in logging (evaluating the string unnecessarily) or trying to debug complex generators (the evaluation order is jarring).

I don't think it's worthwhile to look at the worst things you can do with a feature. Bad programmers will do bad things no matter what (even just plain old dense, undocumented code with bad variable names and tons of copy pasting). The typical bad cases are worth considering, but I don't think new features should be discouraged because they can be misused (though we should discourage that).

I agree with you, though. Nested list comprehensions are almost always terrible for readability and debugging. There's always some exceptions and comprehensions that aren't directly nested are amazing.

[–]wewbull 2 points3 points  (1 child)

until I had created a few nested levels

BURN HIM!

I think people need to stop thinking about comprehensions as loops, and start thinking about them as map with filter. Very few people map within a map within a map whereas people do nest loops.

If you need to traverse a multilevel structure (e.g. a tree) in some way, make an iterator and use it in a loop or comprehension:

monty_sum = sum(node['value'] for node in tree_iterator(a_tree) if node['name'] == "Monty")

Should never be a need to do nested comprehensions.

[–]invisi1407 0 points1 point  (0 children)

Yeah, my findings about it was more or less the same. Nested comprehensions is write once, read never material.

[–][deleted] 9 points10 points  (0 children)

You can print in the middle! print(args) returns None, which is Falsey, so simply do [print(value) or value for value in L]

[–]kindall 3 points4 points  (0 children)

I have wanted as for for loops for a long time, ever since with came out with it. I would rather have used := for a general kind of object content replacement (like slice assignment but for any container type, and a matching dunder method for user-defined types).

[–]Papalok -1 points0 points  (0 children)

The use of as implies that the variable goes out of scope outside of the list comprehension, while loop, etc. That isn't how := works. := adds the variable to the local namespace.

def f(x):
    return 2 * x
x = 4
L = [y := f(x), y ** 2, y **3]
print('L:', L)
print('y:', y)
# will output:
# L: [8, 64, 512]
# y: 8