44

我有以下内容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 上从头到尾迭代。

我该怎么做?

编辑 回答评论:

我得到一个句子中字母频率的字典:

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

并需要从中创建一棵霍夫曼树。

例如:

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

我正在使用 python 3.3

4

5 回答 5

67

简单的例子

from collections import OrderedDict

d = 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
于 2016-02-19T04:26:02.437 回答
12

如何从头到尾遍历 OrderedDict ?

任何一个:

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

或者:

z = OrderedDict( ... )
for item in reversed(z.items()):
   # operate on item
于 2014-01-07T22:31:55.250 回答
6

enumerate您可以使用and进行迭代iteritems

dict = OrderedDict()
# ...

for i, (key, value) in enumerate(dict.iteritems()):
    # Do what you want here
于 2017-04-06T18:04:52.660 回答
4

对于 Python 3.x

d = OrderedDict( ... )

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

对于 Python 2.x

d = OrderedDict( ... )

for key, value in d.iteritems():
    print key, value
于 2020-04-21T17:33:06.207 回答
1

请注意,正如adsmith的评论中所指出的,这可能是XY 问题的一个实例,您应该重新考虑您的数据结构。

话虽如此,如果您只需要对最后三个元素进行操作,那么您就不需要迭代。例如:

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')])
>>> 
于 2014-01-07T22:45:24.947 回答