Python迭代字典

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (24)

我有两个字典,我在另一个里面迭代。我想选择下一个项目,每次它在内部循环中迭代,而不是从一开始。

dict1={'a':1 , 'b':2 , 'c':3}
dict2={'x':10, 'y':20, 'z':30}

for key,value in dict1:
   #do something
    for k,v in dict2:
          #do something

当key=‘a’时,它在内循环上迭代,并根据循环中的代码执行一些操作,假设它所选择的操作在指令2中是‘x’。现在,当我必须用key=‘b’迭代时,我希望内部循环的迭代从‘y’开始,因为‘x’已经被选中了。

提问于
用户回答回答于

首先,for key,value in dict1不做你想做的事-它只是在键值。如果您想在键值对上迭代,则需要for key, value in dict1.items()...

同时,听起来你想要的是锁步迭代,而不是嵌套迭代?如果是的话,你想要zip职能:

for (k1, v1), (k2, v2) in zip(dict1.items(), dict2.items()):
    # do something

但是请注意,这给出的排序实际上是任意的,因为DECTS的排序本质上是任意的。所以,如果你喜欢('a', 'x'),然后('b', 'y')等等,以及满意('a', 'y'),然后('b', 'x'),然后zip就是你想要的。如果不是,那就不是。

(如果你期望你的dict如果要有一些固有的顺序,如插入顺序、排序顺序或其他任何东西,则必须使用不同的类。例如,collections.OrderedDict行为像字典,但保持插入顺序。)


如果您想要更复杂的东西,请将迭代移到dict2以编程方式无法在一行中表示,您可以始终使用迭代协议手动:

iter2 = iter(dict2.items())
for k1, v1 in dict1.items():
    k2, v2 = next(iter2)
    # do something
    # maybe do another k2, v2 = next(iter2)
    # maybe restart iter2 = iter(dict2.items())
    # and so on

正如医生们所解释的,当next(iter2)最后,它会引发StopIteration...。如果你不想那样怎么办?也许你想,正如你在评论中建议的那样,重新开始?你可以通过StopIteration,或者使用next检查。例如:

try:
    k2, v2 = next(iter2)
except StopIteration:
    iter2 = iter(dict2.items())
    k2, v2 = next(iter2)

或者您甚至可以编写循环迭代包装器:

def circular_iterate(iterable_factory):
    while True:
        yield from iterable_factory():

在Python#number0#或更早版本中,您必须替换yield from有内环的:

def circular_iterate(iterable_factory):
    while True:
        for value in iterable_factory():
            yield value

现在:

iter2 = circular_iterate(dict2.items) # note, not dict2.items()

如果您试图跟踪的不仅仅是“当前位置”,您可能需要一个额外的数据结构。例如,如果您想跳过到目前为止看到的所有键,请使用set到目前为止看到的钥匙,或者set没有看到的键:

seen_items_2 = set()
for k1, v1 in dict1.items():
    for k2, v2 in dict2.items():
        if k2 in seen_items_2:
            continue
        seen_items_2.add(k2)
        # do something

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励