[Python-ideas] Integrate some itertools into the Python syntax
Terry Reedy
tjreedy at udel.edu
Mon Mar 28 17:46:27 EDT 2016
On 3/27/2016 11:26 PM, Chris Barker - NOAA Federal wrote:
> But range used to produce a list. So for lips were, in the beginning,
> about iterating, yes, but iterating through a sequence, not an
> arbitrary iterables. I may be wrong here, but I started using Python
> in version 1.5, and I'm pretty sure the iterator protocol did not
> exist then -- I know for sure I learned about it far later.
The current iterator protocol, based on __iter__, __next__, and
StopIteration, was added in 2.2. The original iteration protocol, now
called the 'sequence protocol', was based on __getitem__(count) and
IndexError. Except for not requiring a __length__ method, it required
that what we now call an 'iterable' pretend to be a sequence. It is
still supported by iter().
https://docs.python.org/3/library/functions.html#iter
With the additional changes to builtins in 3.0, there has definitely
been a shift of emphasis from lists and sequences to iterables and
iterators.
---
General response to thread: In spite of this, I am not in favor of
trying to force-fit itertools, in particular islice, into syntax.
Iterables for which slicing makes sense are free to directly support
non-destructive slicing in a __getitem__ method. It does not bother me
that destructive slicing of iterators requires a different syntax.
Because of the difference between non-destructive and destructive
slicing, the goal of making the same code work for sequences and
iterators cannot work beyond a single slice. Suppose one wants to
process the first 5 and then the next 5 items of an iterable. The
necessary code is different for sequences and iterators.
from itertools import islice
rs = range(10)
ri = iter(rs)
print(list(islice(rs, 0, 5)))
print(list(islice(rs, 0, 5)))
print()
print(list(islice(ri, 0, 5)))
print(list(islice(ri, 0, 5))) # works for iterators
print()
ri = iter(rs)
print(list(islice(rs, 0, 5)))
print(list(islice(rs, 5, 10))) # works for sequences
print()
print(list(islice(ri, 0, 5)))
print(list(islice(ri, 5, 10)))
#
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[]
How anyone written and experimented with using a 'syntax-iterator' class
to test the idea? Has such to uploaded to PyPI?
import itertools
class Iter: # syntax-intergrated iterator
def __init__(self, iterable):
self.it = iter(iterable)
def __iter__(self):
return self
def __next__(self):
return next(self.it)
def __getitem__(self, what):
if isistance(what, slice):
return itertools.islice(
what.start or 0, what.stop, what.step or 1)
def __add__(self, other):
return itertools.chain(self, other)
# for more that two iterables, chain(a, b, c, ...) will run faster
...
Then, in the current idiom for a function of an iterable:
def f(args, iterable, args):
it = iter(iterable)
one could replace 'iter' with 'Iter' and proceed to use proposed
iterator syntax within the function.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list