Stefan Ram 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.
That is called "generator expression". When it does not modify the values one usually creates the iterator with k = iter(range(3, 5)). > Now I can insert the "generator" »k« into a function call, > but a spread operator should cannot be used there. > > |>>> sum( k ) > |7 > > »sum« expects exactly two arguments, and this is what »k« > provides. No. sum() requires one iterable and accepts an optional start value. You are passing the iterable only, as may be verified with >>> k = (x for x in [["a"], ["b"]]) >>> sum(k) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'list' versus >>> k = (x for x in [["a"], ["b"]]) >>> sum(k, []) ['a', 'b'] As with iterators in general once they are exhausted they stay exhausted: >>> k = (i for i in range(3, 5)) >>> sum(k) 7 >>> sum(k) 0 (you can but shouldn't make your own that doesn't follow that convention) > 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] I have not seen that, I think. The common way is probably >>> list("foo") ['f', 'o', 'o'] rather than >>> [*"foo"] ['f', 'o', 'o'] and >>> tuple("bar") ('b', 'a', 'r') rather than >>> *"bar", ('b', 'a', 'r') As demonstrated this works with arbitrary iterables, not just generator expressions. -- https://mail.python.org/mailman/listinfo/python-list