[Python-ideas] + operator on generators

Erik Bray erik.m.bray at gmail.com
Fri Jun 30 08:22:22 EDT 2017


On Fri, Jun 30, 2017 at 1:09 AM, Jan Kaliszewski <zuo at chopin.edu.pl> wrote:
> 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.

I actually really like this proposal, in additional to the original
proposal of using '+' to chain generators--I don't think it
necessarily needs to be extended to *all* iterables.  But this
proposal goes one better.  I just have to wonder what kind of strange
unexpected bugs would result.  For example now you could add a list to
a string:

    >>> list(['a', 'b', 'c'] + 'def')
    ['a', 'b', 'c', 'd', 'e', 'f']

Personally, I really like this and find it natural.  But it will break
anything expecting this to be a TypeError.


More information about the Python-ideas mailing list