30 Jun
2017
30 Jun
'17
5:52 p.m.
On Fri, Jun 30, 2017 at 1:09 AM, Jan Kaliszewskiwrote: > 2017-06-25 Serhiy Storchaka 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.