Explanation of this Python language feature? [x for x in x for x in x] (to flatten a nested list)

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Mar 24 15:04:59 CET 2014


On Mon, 24 Mar 2014 22:49:38 +1100, Chris Angelico wrote:

> On Mon, Mar 24, 2014 at 8:55 PM, Marko Rauhamaa <marko at pacujo.net>
> wrote:

>> You never *need* (Python's) lambda for anything. Inner functions are
>> more capable and almost always more readable. It doesn't hurt to have
>> lambda, but I don't find any use for it, either.

Marko has missed an obvious use: lambda is the *only* solution when you 
need a function embedded in an expression. You simply cannot do so 
otherwise. It is truly astonishing that two people here who are such keen 
supporters of functional programming, Marko and Mark Harris, are so 
dismissive of lambda, and so forced to write declarative code using def.


> They're often not more readable. A lot of people seem to equate
> "verbose" with "readable", possibly by faulty extrapolation from
> unreadably crunched code with one-letter variables and no line breaks.
> But which of these is truly more readable?
> 
> squares = []
> for n in range(30):
>     squares.append(n * n)
> 
> squares = [n * n for n in range(30)]

Readable for whom?

List comprehension syntax is often completely obscure to beginners. A 
beginner would say that the explicit for-loop is more readable.

Actually, a *real* beginner, whose main programming experience before 
Python was Pascal, would probably even say that the first example was an 
unreadable mess. What's range(30)? What's this ".append" business? What 
does [] mean? I know this because I was this beginner, once. The first 
few times I tried reading Python code, I couldn't make head or tail of 
it. "for" I recognised, because it was the same keyword as Pascal and 
Hypertalk use. Pretty much everything else might as well have been 
Bulgarian.

This was before the public internet, there was no Google, no tutorials I 
could look up. It was only after a colleague convinced me that it would 
be a good language to learn that I bought an actual dead tree book and 
sat down and learned how to read Python.

I think that Python's reputation of being "executable pseudo-code" is 
sometimes harmful. It fools people into thinking that unless Aunt Tilly 
can understand a language feature, it's somehow a failure. Hence the 
arguments by Mark against lambda.

http://www.catb.org/jargon/html/A/Aunt-Tillie.html

But nobody expects Aunt Tilly to read Scheme or C++ or Go without at 
least a bit of learning -- or even Esperanto or French or Latin. You 
still need to learn the syntax and the vocabulary, and have some idea of 
the basic concepts. The same applies to Python. The learning curve may be 
more gentle, but there is still a learning curve. And that is perfectly 
fine.

So while I agree with you that, to a moderately fluent Python speaker, 
not a beginner but not an expert either, the list comprehension is more 
readable, for a beginner (one who has a basic Python vocab but isn't 
fluent yet) the for-loop will probably be more readable.


> Similarly, there are plenty of cases where a nameless function is MUCH
> clearer than breaking it out into a separate def and then using the name
> once. Do you name the function for what it does internally?
> 
> def get_oneth_element_index(item):
>     return item[1].index
> L.sort(key=get_oneth_element_index)
> 
> Or for how you're using it?
> 
> def keyfunc(item):
>     return item[1].index
> L.sort(key=keyfunc)

Why not both?! Don't forget to make it private so some other piece of 
code doesn't use it. Or better still, delete it when done!

def _get_oneth_element_index_to_use_as_keyfunc_when_sorting_L(item):
    return item[1].index

L.sort(key=_get_oneth_element_index_to_use_as_keyfunc_when_sorting_L)
del _get_oneth_element_index_to_use_as_keyfunc_when_sorting_L

Four lines of code to do what lambda lets you do in one. And people still 
insist that lambda is pointless. Maybe they're being paid by the line.


> Or do you just shortcut the whole thing by inlining it?
> 
> L.sort(key=lambda item:item[1].index)

Exactly.




-- 
Steven D'Aprano
http://import-that.dreamwidth.org/



More information about the Python-list mailing list