I want to iterate through two lists of different size, but not at the same pace (I only found answers for parallel iteration). For instance, consider two sorted lists that contain the same kind of elements and I want to do something on the elements according to the fact they are in only one list or in both lists, using a common traversal of the two lists.
I would know how to do that using indices, but is there a way to do that properly with iterators ?
I have something along the lines of:
list1=[...]
list2=[...]
it1=iter(list1)
it2=iter(list2)
try:
while True:
e1=it1.next()
e2=it2.next()
while compare(e1,e2):
doSomething1(e1)
e1=it1.next()
while compare(e2,e1):
doSomething2(e2)
e2=it2.next()
doSomething3(e1,e2)
except StopIteration:
pass
# do something with the rest of the list that is at end
When the StopIteration is raised, I do not know which list is at end and I don't know how to access the remaining elements: calling next() to check for exception will make me skip an element in the longer list, accessing directly e1 or e2 will make me access the last element of the shorter list a second time.
I can imagine several workarounds, like having the try/except around each next() but all my ideas seems more complex than just using indices...
For a simple working example of the code above, you can use
def compare(e1,e2): return e1<e2
def doSomething1(e1): print "list1: %d"%e1
def doSomething2(e1): print "list2: %d"%e1
def doSomething3(e1,e2): print "common: %d"%e1
list1=[1,2,5,6,8,10,23,56]
list2=[3,4,5,10]
Iterators have a __length_hint__
which will return the (estimated) number of remaining elements to iterate over. The accuracy of this depends on the type of your iterator, and I can't guarantee it would work on non-CPython implementations.
x = [1,2,3,4,5]
y = iter(x)
print y.__length_hint__() # prints 5
print y.next # prints 1
...
In your StopIteration catch, you can check which iterator has remaining members and act based on that.
list1=[...]
list2=[...]
it1=iter(list1)
it2=iter(list2)
try:
while True:
e1=it1.next()
e2=it2.next()
while compare(e1,e2):
doSomething1(e1)
e1=it1.next()
while compare(e2,e1):
doSomething2(e2)
e2=it2.next()
doSomething3(e1,e2)
except StopIteration:
if it1.__length_hint__() > 0:
#handle unhandled list1 items.
elif it2.__length_hint__() > 0:
#handle unhandled list2 items.
else:
#both lists have been exhausted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With