[Python-ideas] How assignment should work with generators?

Steven D'Aprano steve at pearwood.info
Mon Nov 27 09:13:14 EST 2017


On Mon, Nov 27, 2017 at 03:31:38PM +0300, Kirill Balunov wrote:

> As I can see at the moment, these cases should behave differently:
> 
> >>> x, y = [1,2,3,4]             # must raise ValueError
> >>> x, y = iter([1,2,3,4])      # should work

I *completely disagree* that they should behave differently. That would 
be a radical change to the current equivalency between iterators and 
other iterables.

Of course iterators support next() (and a few other things), while 
iterables (sequences and others) support slicing, __getitem__, and so 
forth. But when it comes to iteration, they behave exactly the same in 
all ways that I can think of:

  for x in iterable: ...

  list(iterable)

  iter(iterable)

  func(*iterable)

and most importantly for this discussion, iterable unpacking:

  a, b, c = *iterable


They all work the same, regardless of whether `iterable` is an iterator, 
a generator, a list, a tuple, a range object, a custom lazy sequence.

Sure, there are a few differences: iterators generally cannot be 
restarted or rewound, while lazy sequences might be, and eager sequences 
like lists can be. You can't peek into an arbitrary iterator without 
consuming the value. But as far as iteration itself goes, they are all 
the same.



-- 
Steve


More information about the Python-ideas mailing list