[Python-ideas] + operator on generators

Jan Kaliszewski zuo at chopin.edu.pl
Thu Jun 29 19:09:51 EDT 2017


2017-06-25 Serhiy Storchaka <storchaka at gmail.com> dixit:

> 25.06.17 15:06, lucas via Python-ideas пише:

> > I often use generators, and itertools.chain on them.
> > What about providing something like the following:
> > 
> >      a = (n for n in range(2))
> >      b = (n for n in range(2, 4))
> >      tuple(a + b)  # -> 0 1 2 3
[...]
> It would be weird if the addition is only supported for instances of
> the generator class, but not for other iterators. Why (n for n in
> range(2)) 
> + (n for n in range(2, 4)) works, but iter(range(2)) + iter(range(2,
> 4)) and iter([0, 1]) + iter((2, 3)) don't? itertools.chain() supports 
> arbitrary iterators. Therefore you will need to implement the __add__ 
> method for *all* iterators in the world.
> 
> However itertools.chain() accepts not just *iterators*.
[...]

But implementation of the OP's proposal does not need to be based on
__add__ at all.  It could be based on extending the current behaviour of
the `+` operator itself.

Now this behavior is (roughly): try left side's __add__, if failed try
right side's __radd__, if failed raise TypeError.

New behavior could be (again: roughly): try left side's __add__, if
failed try right side's __radd__, if failed try __iter__ of both sides
and chain them (creating a new iterator¹), if failed raise TypeError.

And similarly, for `+=`: try __iadd__..., try __add__..., try
__iter__..., raise TypeError.

Cheers.
*j

¹ Preferably using the existing `yield from` mechanism -- because, in
case of generators, it would provide a way to combine ("concatenate")
*generators*, preserving semantics of all that their __next__(), send(),
throw() nice stuff...


More information about the Python-ideas mailing list