Chapter 8
We can create pairs using list slices as follows:
zip(flat[0::2], flat[1::2])
The islice() function gives us similar capabilities without the overhead of
materializing a list object, and it looks like the following:
flat_iter_1= iter(flat)
flat_iter_2= iter(flat)
zip(islice(flat_iter_1, 0, None, 2), islice(flat_iter_2, 1, None, 2))
We created two independent iterators over a flat list of data points. These might be
two separate iterators over an open file or a database result set. The two iterators
need to be independent so that change in one islice() function doesn't interfere
with the other islice() function.
The two sets of arguments to the islice() function are similar to the flat[0::2]
and flat[1::2] methods. There's no slice-like shorthand, so the start and stop
argument values are required. The step can be omitted and the default value is 1.
This will produce a sequence of two tuples from the original sequence:
[(2, 3), (5, 7), (11, 13), (17, 19), (23, 29), ... (7883, 7901),
(7907, 7919)]
Since islice() works with an iterable, this kind of design will work with extremely
large sets of data. We can use this to pick a subset out of a larger set of data. In
addition to using the filter() or compress() functions, we can also use the
islice(source,0,None,c) method to pick 1/c items from a larger set of data.
Stateful filtering with dropwhile() and takewhile()
The dropwhile() and takewhile() functions are stateful filter functions. They start
in one mode; the given predicate function is a kind of flip-flop that switches the
mode. The dropwhile() function starts in reject mode; when the function becomes
False, it switches to pass mode. The takewhile() function starts in pass mode;
when the given function becomes False, it switches into reject mode.
Since these are filters, both functions will consume the entire iterable. Given an
infinite iterator like the count() function, it will continue indefinitely. Since there's
no simple integer overflow in Python, an ill-considered use of dropwhile() or
takewhile() functions won't crash after a few billion iterations with integer
overflow. It really can run for a very, very long time.