我有两个字典,一个在另一个里面迭代。我希望每次在内部循环内迭代时选择下一项,而不是从头开始。
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
当loop.Suppose =‘a’时,它迭代内部循环,并根据它选择的操作在dict2中是'x‘的那个key中的代码执行一些操作。现在,当我必须使用key='b‘进行迭代时,我希望内部循环的迭代从'y’开始,因为'x‘已经被选中。
发布于 2014-01-24 05:37:00
首先,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')
也很满意,那么zip
就是您想要的。如果不是,它就不是。
(如果您希望dict
具有某些固有的顺序,如插入顺序、排序顺序或其他任何顺序,则必须使用不同的类。例如,collections.OrderedDict
的作用类似于字典,但它保持插入顺序。)
如果你想要一些更复杂的东西,你可以通过编程的方式在dict2
上移动迭代,而不是用一行程序来表达,你总是可以手动使用iteration protocol:
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():
在Python3.2或更早版本中,您必须将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
https://stackoverflow.com/questions/21319774
复制相似问题