[Python-Dev] itertools addition: getitem()
Walter Dörwald
walter at livinglogic.de
Mon Jul 9 08:16:35 CEST 2007
Raymond Hettinger wrote:
> [Walter Dörwald]
>> I'd like to propose the following addition to itertools: A function
>> itertools.getitem() which is basically equivalent to the following
>> python code:
>>
>> _default = object()
>>
>> def getitem(iterable, index, default=_default):
>> try:
>> return list(iterable)[index]
>> except IndexError:
>> if default is _default:
>> raise
>> return default
>>
>> but without materializing the complete list. Negative indexes are
>> supported too (this requires additional temporary storage for abs(index)
>> objects).
>
> Why not use the existing islice() function?
>
> x = list(islice(iterable, i, i+1)) or default
This doesn't work, because it produces a list
>>> list(islice(xrange(10), 2, 3)) or 42
[2]
The following would work:
x = (list(islice(iterable, i, i+1)) or [default])[0]
However islice() doesn't support negative indexes, getitem() does.
> Also, as a practical matter, I think it is a bad idea to introduce
> __getitem__ style access to itertools because the starting point
> moves with each consecutive access:
>
> # access items 0, 2, 5, 9, 14, 20, ...
> for i in range(10):
> print getitem(iterable, i)
>
> Worse, this behavior changes depending on whether the iterable
> is re-iterable (a string would yield consecutive items while a
> generator would skip around as shown above).
islice() has the same "problem":
>>> from itertools import *
>>> iterable = iter(xrange(100))
>>> for i in range(10):
... print list(islice(iterable, i, i+1))
[0]
[2]
[5]
[9]
[14]
[20]
[27]
[35]
[44]
[54]
>>> iterable = xrange(100)
>>> for i in range(10):
... print list(islice(iterable, i, i+1))
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
> Besides being a bug factory, I think the getitem proposal would
> tend to steer people down the wrong road, away from more
> natural solutions to problems involving iterators.
I don't think that
(list(islice(iterable, i, i+1)) or [default])[0]
is more natural than
getitem(iterable, i, default)
> A basic step
> in learning the language is to differentiate between sequences
> and general iterators -- we should not conflate the two.
Servus,
Walter
More information about the Python-Dev
mailing list