2014-01-23 217 views
16

我有兩個字典,我在其中一個迭代它。 我想每次迭代內循環而不是從頭開始時選擇下一個項目。python迭代字典

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 

當鍵=「A」,它遍歷內環和做一些動作根據在loop.Suppose代碼,它的行動,它在選定dict2「X」是。 現在,當我必須迭代key ='b'時,我希望內部循環的迭代從'y'開始,因爲'x'已經被選中。

+0

所以基本上你想在同一時間通過兩個步驟? – StephenTG

+0

是的。 @StephenTG – Mark

+2

字典中的鍵是無序的。 「dict1」中的任何鍵都可以與「dict2」中的任何鍵配對。 – unutbu

回答

13

首先,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 

但需要注意的是排序這給你實際上是任意的,因爲類型的字典的順序本質上是任意的。所以,如果你滿意​​,那麼('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(): 

在Python 3.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 
+0

我已經制作了字典OrderedDict.Just外部的一個 – Mark

+0

我認爲這將解決問題。我想知道如果下一個(iter2)將開始,如果它開始,如果它碰到字典的末尾 – Mark

+0

@Nikhil:不, next(iter2)'如果達到最終結果,將會產生'StopIteration';我會解釋如何做你想做的事,並添加鏈接,這樣你就可以爲自己找出答案(遺憾忘記)。給我一點時間來編輯答案。 – abarnert