【问题标题】:Deal with StopIteration exception when iterating on two lists of different size迭代两个不同大小的列表时处理 StopIteration 异常
【发布时间】:2016-07-11 22:27:34
【问题描述】:

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

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

我有一些类似的东西:

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]

【问题讨论】:

  • 如果列表中通常没有 None 值,您可以用 None 填充较短的列表以匹配其他列表的长度。
  • 我认为这不会有帮助,因为我不希望我的两个迭代器并行推进。

标签: python list exception iterator


【解决方案1】:

迭代器有一个__length_hint__,它将返回要迭代的剩余元素的(估计)数量。其准确性取决于您的迭代器的类型,我不能保证它适用于非 CPython 实现。

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

在您的 StopIteration 捕获中,您可以检查哪个迭代器具有剩余成员并据此采取行动。

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.

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
  • 2016-08-02
  • 1970-01-01
  • 2013-12-19
  • 2022-11-03
  • 1970-01-01
  • 2016-11-11
相关资源
最近更新 更多