[Python-ideas] + operator on generators
David Mertz
mertz at gnosis.cx
Tue Jun 27 03:47:40 EDT 2017
On Tue, Jun 27, 2017 at 12:12 AM, Steven D'Aprano <steve at pearwood.info>
wrote:
> > > I have a counter-proposal: introduce the iterator chaining operator
> "&":
> > > iterable & iterable --> itertools.chain(iterable, iterable)
> >
> > In [1]: import numpy as np
> > In [2]: import itertools
> > In [3]: a, b = np.array([1,2,3]), np.array([4,5,6])
> > In [4]: a & b
> > Out[4]: array([0, 0, 2])
> > In [5]: a + b
> > Out[5]: array([5, 7, 9])
> > In [6]: list(itertools.chain(a, b))
> > Out[6]: [1, 2, 3, 4, 5, 6]
> >
> > These are all distinct, useful, and well-defined behaviors.
>
> - keep the existing __and__ and __rand__ behaviour;
> - if they are not defined, and both operands x, y are iterable,
> return chain(x, y);
>
I understand. But it invites confusion about just what the `&` operator
will do for a given iterable. For NumPy itself, you don't really want to
spell `chain(a, b)` so much. But you CAN, they are iterables. The
idiomatic way is:
>>> np.concat((a,b))
array([1, 2, 3, 4, 5, 6])
However, for "any old iterable" it feels very strange to need to inspect
the .__and__() and .__rand__ () methods of the things on both sides before
you know WHAT operator it is.
Maybe if you are confident a and b are exactly NumPy arrays it is obvious,
but what about:
from some_array_library import a
from other_array_library import b
What do you think `a & b` will do under your proposal? Yes, I understand
it's deterministic... but it's far from *obvious*. This isn't even doing
something pathological like defining both `.__iter__()` and `.__and__()` on
the same class... which honestly, isn't even all that pathological; I can
imagine real-world use cases.
I think that chaining iterators is common enough and important enough in
> Python 3 to deserve an operator. While lists are still important, a lot
> of things which were lists are now lazily generated iterators, and we
> often need to concatenate them. itertools.chain() is less convenient
> than it should be.
>
I actually completely agree! I just wish I could think of a good character
that doesn't have some very different meaning in other well-known contexts
(even among iterables).
Some straw men:
both = a ⊕ b
both = a ⇢ b
Either of those look pretty nice to me, but neither is easy to enter on
most keyboards.
I think I wouldn't mind `&` if it only worked on iteraTORS. But then it
loses many of the use cases. I'd like this, after all:
for i in range(10)⇢[20,19,18]⇢itertools.count(100):
if i>N: break
...
--
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons. Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170627/46a0ee37/attachment-0001.html>
More information about the Python-ideas
mailing list