Generators, files and infinite iterators don't support [a:b], but you still need 'the first 10' or 'skip the header'.
Iterators can't be indexed or sliced with [start:stop]. islice provides the same semantics lazily:
islice(it, stop)the firststopitemsislice(it, start, stop)items from indexstartup tostopislice(it, start, stop, step)with a stepstop=Nonemeans "to the end":islice(it, 1, None)skips the first item
Negative values are not allowed, because an iterator doesn't know its length.
islice consumes the underlying iterator as it goes. Skipping 1,000 items means producing and discarding them, so it's O(start), not O(1) like a list slice. And the original iterator is advanced: after list(islice(it, 3)), the next item of it is the fourth.
That last property is useful. Reading a file, next(f) or islice(f, 1, None) skips a header line. Taking repeated islice(it, n) chunks from one iterator is how batching worked before itertools.batched.
Common combos:
islice(count(), 5)the first five numbersnext(islice(it, n, None), default)the n-th item (thenthrecipe)list(islice(sorted_generator, 10))a top-10 preview without consuming everything
Example
from itertools import count, islice
def squares():
for n in count():
yield n * n
print(list(islice(squares(), 5))) # [0, 1, 4, 9, 16]
print(list(islice(squares(), 2, 8, 2))) # [4, 16, 36]
it = iter(range(10))
print(list(islice(it, 3))) # [0, 1, 2]
print(next(it)) # 3 -- original advanced
lines = iter(["id,name", "1,ann", "2,bob"])
for row in islice(lines, 1, None): # skip header
print(row)
# 1,ann
# 2,bob
print(next(islice(squares(), 10, None))) # 100Remember
islice(it, start, stop, step)slices any iterator lazily- Skipping costs O(start) and advances the original iterator
- No negative indices: iterators have no known length
Watch out for
- Calling
islice(it, -5, None)to get the last items; usecollections.deque(it, maxlen=5)instead.