[issue27384] itertools islice consumes items when given negative range

Raymond Hettinger report at bugs.python.org
Tue Jun 28 19:20:13 EDT 2016


Raymond Hettinger added the comment:

"Surprising" is in the eye of the beholder.  Having islice() always consume at least "start" number of values seems reasonable enough and it is the documented behavior: "If start is non-zero, then elements from the iterable are skipped until start is reached. ... If stop is None, then iteration continues until the iterator is exhausted, if at all; otherwise, it stops at the specified position."  

That covers a lot of cases including the existing consume() recipe and what happens to the iterator if it supplies fewer than start elements: it=iter('abc'); list(islice(it, 4, 4)); print(list(it)).  Also, to my eyes, the current behavior seems like a natural and smooth transition as the arguments transition towards cross-over:

    >>> from itertools import islice

    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 4)), list(it))
    ['C', 'D'] ['E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 3)), list(it))
    ['C'] ['D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 2)), list(it))
    [] ['C', 'D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 1)), list(it))
    [] ['C', 'D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 0)), list(it))
    [] ['C', 'D', 'E', 'F', 'G']

    >>> it = iter('ABCDEFG'); print(list(islice(it, 0, 2)), list(it))
    ['A', 'B'] ['C', 'D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 1, 2)), list(it))
    ['B'] ['C', 'D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 2, 2)), list(it))
    [] ['C', 'D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 3, 2)), list(it))
    [] ['D', 'E', 'F', 'G']
    >>> it = iter('ABCDEFG'); print(list(islice(it, 4, 2)), list(it))
    [] ['E', 'F', 'G']

Putting in your suggested optimization to treat start > stop as being fully consumed from the outset would have some big disadvantages.  It would break existing code relying on the current reasonable and documented behavior of always eating at least "start" elements.  And it would incentivize a new and weird idiom for "consume" as islice(it, n, 0).

As far as I can tell, the current behavior hasn't been problematic for anyone in the almost 15 year history of the itertools module, so it is hard to get excited enough about this to want to incur those disadvantages.

----------
priority: normal -> 
resolution:  -> not a bug
status: open -> closed

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27384>
_______________________________________


More information about the Python-bugs-list mailing list