迭代两个不同大小的列表

时间:2016-03-24 10:47:24

标签: python list exception iterator

我想迭代两个不同大小的列表,但不是以相同的速度(我只找到并行迭代的答案)。例如,考虑两个包含相同类型元素的排序列表,我想根据它们只在一个列表或两个列表中的事实对元素执行某些操作,使用两个列表的常见遍历。

我知道如何使用索引来做到这一点,但有没有办法用迭代器正确地做到这一点?

我有以下几点:

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

当引发StopIteration时,我不知道哪个列表在最后,我不知道如何访问其余元素:调用next()来检查异常将使我跳过更长列表中的元素,直接访问e1或e2将使我第二次访问较短列表的最后一个元素。

我可以想象几个解决方法,比如在每个next()周围使用try / except但是我的所有想法似乎都比使用索引更复杂......

有关上述代码的简单工作示例,您可以使用

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]

1 个答案:

答案 0 :(得分:2)

迭代器有__length_hint__,它将返回(估计的)剩余元素的数量以进行迭代。这种准确性取决于迭代器的类型,我不能保证它可以在非CPython实现上工作。

x = [1,2,3,4,5]
y = iter(x)
print y.__length_hint__() # prints 5
print y.next # prints 1
...

在StopIteration catch中,您可以检查哪些迭代器具有剩余成员并根据该行为进行操作。

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.