Iterating through two lists
Robert Amesz
sheershion at mailexpire.com
Sat May 25 20:08:16 EDT 2002
Boudewijn Rempt wrote:
> jb wrote:
>
>> I have two lists, x and y with the property len(x) = len(y).
>>
>> I should like to achive this (x is a list of class instances)
>>
>> for (a,b) in (x,y): a.f(b)
>>
>> Is there a fancy way of doing this or have I to introduce an
>> auxillary counter (that is very easy but maybe not very "lispy",
>> that is "python-like").
>>
>
> Is this what you want?
>
>>>> a=[1,2,3]
>>>> b=['a','b','c']
>>>> map(None, a, b)
> [(1, 'a'), (2, 'b'), (3, 'c')]
>>>> for t in map(None, a, b):
> ... print t
> ...
> (1, 'a')
> (2, 'b')
> (3, 'c')
>>>> for i, j in map(None, a, b):
> ... print i, j
> ...
> 1 a
> 2 b
> 3 c
With Python 2.2, you'd expect to be able do things like that with some
iterator magic, but oddly enough I couldn't find anything. No matter, I
can do that myself:
--- cut ---
class paralleliter:
def __init__(self, *sequences):
if not sequences:
raise ValueError("Nothing to iterate over")
self.iterators = map(iter, sequences)
def __iter__(self):
return self
def next(self):
return [x.next() for x in self.iterators]
l1 = [1, 2, 3]
l2 = ['a', 'b', 'c']
for r in paralleliter(l1, l2):
print r
--- cut ---
This results in:
[1, 'a'][2, 'b'][3, 'c']
You might argue that paralleliter should raise an exception when
sequences are of unequal length. Well, this isn't terribly hard to
implement, even though you _cannot_ use len() to test this, because
iterators have no predetermined length. However, the code loses a lot
of its elegance this way:
--- cut ---
class paralleliter2:
def __init__(self, *sequences):
if not sequences:
raise ValueError("Nothing to iterate over")
self.iterators = map(iter, sequences)
def __iter__(self):
return self
def next(self):
result = []
for x in self.iterators:
try:
result.append(x.next())
except StopIteration:
pass
if len(result) == 0:
raise StopIteration
if len(result) <> len(self.iterators):
raise ValueError("Sequences are of unequal length")
return result
--- cut ---
Personally, I'd like this type of parallel iterator (and perhaps a
serial one, too) to be added to the set of builtin functions: this type
of iteration comes up time and time again in this newsgroup, and it
would be nice to have a universal and canonical way to settle it once
and for all.
Robert Amesz
More information about the Python-list
mailing list