2014-01-07 115 views
11

我有以下OrderedDict:遍歷OrderedDict蟒蛇

OrderedDict([('r', 1), ('s', 1), ('a', 1), ('n', 1), ('y', 1)]) 

這實際上提出了一個字一個字母的頻率。

在第一步 - 我會拿最後兩個元素來創建這樣的聯合元組;

pair1 = list.popitem() 
    pair2 = list.popitem() 
    merge_list = (pair1[0],pair2[0]) 
    new_pair = {} 
    new_pair[merge_list] = str(pair1[1] + pair2[1]) 
    list.update(new_pair); 

這對我創建了以下OrderedList:

OrderedDict([('r', 1), ('s', 1), ('a', 1), (('y', 'n'), '2')]) 

現在我想基於值的較低和什麼是每次服用過去三年決定遍歷元素,聯盟對象。

例如上面的列表將轉向;

OrderedDict([('r', 1), (('s', 'a'), '2'), (('y', 'n'), '2')]) 

但上面是:

OrderedDict([ ('r', 1), ('s', 2), ('a', 1), (('y', 'n'), '2')]) 

其結果將是:

OrderedDict([('r', 1), ('s', 2), (('a','y', 'n'), '3')]) 

,因爲我想離開的人有更小的值

我試着做它本身,但不知道如何通過OrderedDict從頭到尾迭代。

我該怎麼辦?

EDITED 接聽評論:

我收到一封信的頻率的字典中的一句話:

{ 's':1, 'a':1, 'n':1, 'y': 1} 

,並需要從它創建一個哈夫曼樹。

例如:

((s,a),(n,y)) 

我使用Python 3.3

+2

解決您的[XY問題(HTTP:// meta.stackexchange.com/questions/66377/what-is-the-xy-problem)和這將更容易得到答案!用外行的話說 - 告訴我們你的廣泛目標是什麼,而不是如何解決你的特定方式。 –

+0

你的意思是'顛倒了(OrderedDict.items())'? –

+0

@adsmith你是對的 - 我編輯我的問題,實際上我需要做 – Dejell

回答

9

如何遍歷從末端開始了一個多OrderedDict?

或者:

z = OrderedDict(...) 
for item in z.items()[::-1]: 
    # operate on item 

或者:

z = OrderedDict(...) 
for item in reversed(z.items()): 
    # operate on item 
+0

會顛倒(z.items())更改順序?因爲我想保留更多迭代 – Dejell

+1

'reversed()'創建一個新列表,這是傳入列表的反向。它不會改變原始'OrderedDict.'的任何方面 –

+0

這導致'dict_items不是可逆腳本'或'dict_items不可逆轉',分別對我來說(python 3)。我必須這樣做:'爲反轉鍵(z.keys()):#使用鍵獲得值然後做東西' –

1

需要注意的是,在由adsmith的評論指出,這可能是一個XY Problem的一個實例,你應該重新考慮你的數據結構。

話雖如此,如果你只需要操作最後三個元素,那麼你不需要迭代。例如:

MergeInfo = namedtuple('MergeInfo', ['sum', 'toMerge1', 'toMerge2', 'toCopy']) 

def mergeLastThree(letters): 
    if len(letters) < 3: 
     return False 

    last = letters.popitem() 
    last_1 = letters.popitem() 
    last_2 = letters.popitem() 

    sum01 = MergeInfo(int(last[1]) + int(last_1[1]), last, last_1, last_2) 
    sum12 = MergeInfo(int(last_1[1]) + int(last_2[1]), last_1, last_2, last) 
    sum02 = MergeInfo(int(last[1]) + int(last_2[1]), last, last_2, last_1) 

    mergeInfo = min((sum01, sum12, sum02), key = lambda s: s.sum) 

    merged = ((mergeInfo.toMerge1[0], mergeInfo.toMerge2[0]), str(mergeInfo.sum)) 

    letters[merged[0]] = merged[1] 
    letters[mergeInfo.toCopy[0]] = mergeInfo.toCopy[1] 

    return True 

然後有:

letters = OrderedDict([('r', 1), ('s', 1), ('a', 1), ('n', 1), ('y', 1)]) 

print letters 
mergeLastThree(letters) 
print letters 
mergeLastThree(letters) 
print letters 

產地:

>>> OrderedDict([('r', 1), ('s', 1), ('a', 1), ('n', 1), ('y', 1)]) 
OrderedDict([('r', 1), ('s', 1), (('y', 'n'), '2'), ('a', 1)]) 
OrderedDict([('r', 1), (('a', 's'), '2'), (('y', 'n'), '2')]) 

和融合整個結構完全,你只是需要:

print letters 
while mergeLastThree(letters): 
    pass 
print letters 

其中給出:

>>> OrderedDict([('r', 1), ('s', 1), ('a', 1), ('n', 1), ('y', 1)]) 
OrderedDict([((('a', 's'), 'r'), '3'), (('y', 'n'), '2')]) 
>>> 
18

簡單的例子

from collections import OrderedDict 

d = collections.OrderedDict() 
d['a'] = 1 
d['b'] = 2 
d['c'] = 3 

for key, value in d.items(): 
    print key, value 

輸出:

a 1 
b 2 
c 3 
+0

這是用於python 3還是2? –

+0

@CharlieParker 2 –

1

可以遍歷使用enumerateiteritems

dict = OrderedDict() 
# ... 

for i, (key, value) in enumerate(dict.iteritems()): 
    # Do what you want here