detaching comprehensions
Ian Kelly
ian.g.kelly at gmail.com
Fri Sep 8 16:46:16 EDT 2017
On Fri, Sep 8, 2017 at 2:24 PM, Stefan Ram <ram at zedat.fu-berlin.de> wrote:
> Maybe you all know this, but to me this is something new.
> I learnt it by trial and error in the Python 3.6.0 console.
>
> Most will know list comprehensions:
>
> |>>> [ i for i in range( 3, 5 )]
> |[3, 4]
>
> I found out that the comprehension can be detached from the list:
>
> |>>> k =( i for i in range( 3, 5 ))
>
> but one must use an extra pair of parentheses around it in the
> assignment.
You don't need an *extra* pair of parentheses per se. The generator
expression simply must be enclosed in parentheses. This is perfectly
valid:
py> sum(i for i in range(3, 5))
> Now I can insert the "generator" »k« into a function call,
> but a spread operator should cannot be used there.
If you mean the * syntax, certainly it can.
> |>>> sum( k )
> |7
But you don't want it in this case, because that would do the wrong thing.
> »sum« expects exactly two arguments, and this is what »k«
> provides.
Not exactly. sum(k) is only providing the first argument to sum. The
first argument is required to be an iterable, which is what k is. The
second argument, "start", takes its default value of 0. This is
effectively equivalent to calling sum([3, 4]).
sum(*k) on the other hand would spread the values of k over the
arguments of sum and would be equivalent to calling sum(3, 4), which
raises a TypeError because 3 is not iterable.
> But to insert it again into the place where it was "taken
> from", a spread operator is required!
>
> |>>> k =( i for i in range( 3, 5 ))
> |>>> [ *k ]
> |[3, 4]
Alternatively:
py> list(k)
[3, 4]
As a final aside, storing a generator in a temporary variable is
usually bad style because it sets up an expectation that the contents
of the variable could be used more than once, when in fact a generator
can only be iterated over once.
More information about the Python-list
mailing list