Hacker News new | past | comments | ask | show | jobs | submit login

Then it turns into this:

    x = []
    for word in words:
       for letter in word:
          x.append(letter)
Which in addition to being far more verbose and less readable, is also less efficient.



I'll tell you what I tell my team: it's barely more verbose, and the readability is up for extremely serious debate (I mean, everyone understands nested for loops, but the nested list comprehension thing is wierd... why is something that appears way way before the innermost "for" the same as something in that for loop's declaration?)

It may also be less efficient. When I'm shown numbers that the difference between the comprehension and the for loops are (in each specfic instance, or in aggregate for the program in question) is above statistical noise AND it's a significant factor in overall runtime (I won't ever worry about a millisecond when the runtime is 1s), then I'll gladly say: put them in.

Until then, just use the loops. Use of really strange language features that are surprising, not exactly idiomatic (this argument is common for this case) and not shown to be of actual benefit, are detrimental in a polyglot environment.


When I see a list comprehension I can see with a single glance what it's doing. Not so with the 4 line for loop. Comprehensions aren't a strange language feature in Python either...it's one of the central features of Python.

Don't use something until it's proven to yield a great benefit is a very conservative approach. That may be appropriate in some cases, but I'm very glad that I am not in such a team since that would be incredibly frustrating. I much prefer an approach where you go with the choice that's most likely the better one, even if it's not 100% proven better or not a big difference.


I'm talking strictly about multi "for" comprehensions. They just are too confusing to me and most of the people I've worked with ever. But we also use lots (most) python features fully, just that one has been the source of dozens of bugs in this one codebase, not to mention others I've worked on with other people. It is a shitty non-intuitive syntax.

Nested for loops, flatten(), various itertools functions and chained generator expressions all suffice, and I have yet to see them provide measurable slowdown to actual code compared to good algorithms and decent factoring. Like I said, I'll even use multi-for comprehensions if there is a measurable difference over nested for-loops.

Also, I think you are intentionally misrepresenting what I said - when I said don't use "weird stuff" I explicitly excluded idiomatic language things. That includes (for python) single for comprehensions. The multi-for comprehension is something I rarely come across in the wild despite it's long time existence in python - it's a weird one.


I think you are trying to justify your strange preferences after the fact. How exactly were there bugs caused by nested for loops that you encountered? It's not like if you mess up the order it will actually run without throwing an exception. Nested list comprehensions are idiomatic python. It's really strange that you don't let your team use them because you are afraid of them.


Well, Google doesn't recommend it either (http://google-styleguide.googlecode.com/svn/trunk/pyguide.ht...), but I guess they are all bloody noobs or whatever.

I mean, single level comprehension is good. Nested list comprehension is OK only in most trivial cases. In my opinion, if I see how a person uses list comprehension, I can tell, what kind of person this is.

There are people who, for example, do this def all_is_okey_dorey(lst): return all([some_predicate_fn(x) for x in lst])

instead of this def all_is_okey_dorey(lst): for x in lst: if not some_predicate_fn(x): return False return True

and can live with themselves somehow.

Or there are people, who refuse to acknowledge the existence of anything besides Python 3.x and when forced to write in 2.x use list comprehension instead of iterator comprehension.

Thing is, the validity of using nested list comprehension depends not on the amount of for loops you have, but on the thing you want to do with the item. If it's just selection, then it might be ok. If you want to apply some kind of function to it, then it's most probably the case of trying to be too clever.


If you think two loops is not a "simple case" of a list comprehension as Google suggests to use them for, perhaps you shouldn't be doing code reviews. It sounds like your team would be held down by your weak grasp of the language.


The only thing wrong with that list comprehension version is those [ ]

    all(some_predicate_fn(x) for x in lst)
Much better than the loop.


It's much more readable, people won't make mistakes on it the way they do when trying to be too clever with their multiple-for statements in list-comprehensions.

Trying to pack too much on a single line is one of the sins of perl, and I'm happy to read python code that is comfortable being multi-line.


For loops can often be avoided. I would write this particular example in one of these ways, that I think are readable:

    x = []
    for word in words:
        x.extend(word)

    from itertools import chain
    x = [letter for letter in chain(*words)]

    x = list(chain(*words))


Wouldn't chain(*words) require unpacking all of words before feeding it into the chain function, storing a second copy of the word list in memory?


Yes it would, but I don't care about these small efficiencies, say 97% of the time ;)

The lazy version in Python 3 would be this one:

    list(chain(*map(iter, words)))
For Python 2 one has to use itertools.imap instead of map.


It's not all or nothing. One, last? for loop can be list comp.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: