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

Chris Angelico rosuav at gmail.com
Sun Mar 23 23:27:32 EDT 2014


On Mon, Mar 24, 2014 at 1:35 PM, Rhodri James <rhodri at wildebst.org.uk> wrote:
>> Would you not consider this to be declarative?
>>
>>    x = [1, 2, 3]
>
>
> I'm not sure I would.  I look at that line of code and think of it as
> "Create a list...", very much in an imperative manner.  Then again, compared
> with C structs and typedefs and actual honest-to-God type declarations,
> there's precious little in Python I would consider truly declarative.

I'm in the declarative group here. Yes, it has to be implemented as
creating a list and adding three elements to it, but conceptually, it
means "Bind x to a new list with these elements". And as long as
that's the end result, I don't care how it's done; the interpreter's
most welcome to have a "template list" that it copies, or maybe a
literal tuple that gets passed to the list() constructor, or
whatever's most efficient.

It gets a bit messier when there's stuff with side effects, though.
This has to be a bit more imperative:

x = [foo(y), bar(y), quux(y)]

That means "Call foo, bar, and quux, in that order, each with y as an
argument, and bind x to a new list with their return values". And if
Python had a simple notation for calling a series of functions, that
could be written something like this:

funcs = [foo, bar, quux]
x = funcs(y)

which is looking more declarative again. It's now "Take this list of
functions and call them all, and bind x to a list of their return
values". (This could be done, with a callable subclass of list. Call
it a sort of "implicit map" if you like.) Python doesn't have that
syntax, but it does have this:

x = [f(y) for f in funcs]

and I'd say that's reasonably declarative; it should be read like the
previous one: "Take this list of funcs, call each one, and bind x to a
list of their return values". And I could imagine a
parallel-processing version of a list comp that functions like
multiprocessing.Pool.map() and doesn't promise order, which would
*definitely* be declarative.

ChrisA



More information about the Python-list mailing list