Looping in Parallel over Index and Sequence Items
Credit: Alex Martelli
Problem
You need to loop on a sequence, but at each step you also need to know what index into the sequence you have reached.
Solution
Together, the built-in functions
xrange
and zip make this easy. You need only this one
instance of xrange, as it is fully reusable:
indices = xrange(sys.maxint)
Here’s how you use the indices
instance:
for item, index in zip(sequence, indices):
something(item, index)This gives the same semantics as:
for index in range(len(sequence)):
something(sequence[index], index)but the change of emphasis allows greater clarity in many usage contexts.
Another alternative is to use class wrappers:
class Indexed:
def _ _init_ _(self, seq):
self.seq = seq
def _ _getitem_ _(self, i):
return self.seq[i], iFor example:
for item, index in Indexed(sequence):
something(item, index)In Python 2.2, with from _ _future_ _ import generators, you can also use:
def Indexed(sequence):
iterator = iter(sequence)
for index in indices:
yield iterator.next( ), index
# Note that we exit by propagating StopIteration when .next raises it!However, the simplest roughly equivalent way remains the good old:
def Indexed(sequence):
return zip(sequence, indices)Discussion
We often want to loop on a sequence but also need the current index in the loop body. The canonical Pydiom for this is:
for i in range(len(sequence)):
using sequence[i] as the item reference in the loop’s body. However, in many contexts, it is clearer to emphasize ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access