我有两本词典。我在另一首里面迭代。 我希望每次在内循环内而不是从开头迭代时选择下一个项目。
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'时,它迭代内循环并根据该循环中的代码执行一些操作。假设它在dict2中选择的动作为'x'。 现在,当我必须使用key ='b'进行迭代时,我希望内循环的迭代从'y'开始,因为'x'已被选中。
答案 0 :(得分:12)
首先,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
但是请注意,这给你的顺序实际上是任意的,因为dicts的顺序本质上是任意的。因此,如果您对('a', 'x')
,('b', 'y')
等感到满意,也对('a', 'y')
感到满意,那么('b', 'x')
,那么{ {1}}就是你想要的。如果不是,那就不是。
(如果您希望zip
具有某些固有顺序,例如插入顺序,排序顺序或其他任何内容,则必须使用其他类。例如,{{1}就像字典一样,但保持插入顺序。)
如果你想要更复杂的东西,你可以通过编程方式将迭代移动到dict
上,而不能用单行表达,你可以随时手动使用iteration protocol:
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
在Python 3.2或更早版本中,您必须使用内部循环替换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():
现在:
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