【问题标题】:Iterate over OrderedDict in Python在 Python 中迭代 OrderedDict
【发布时间】:2014-01-25 19:43:13
【问题描述】:

我有以下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

【问题讨论】:

  • 解决你的XY Problem,这将更容易得到答案!通俗地说——告诉我们您的广泛目标是什么,而不是如何解决您的特定工作方式。
  • 你的意思是reversed(OrderedDict.items())?
  • @adsmith 你是对的 - 我编辑了我的问题,实际上我需要做什么

标签: python python-3.x dictionary python-3.3 ordereddict


【解决方案1】:

如何在 OrderedDict 上从头到尾迭代?

要么:

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

或者:

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

【讨论】:

  • reversed(z.items()) 会改变顺序吗?因为我想保留它以进行更多迭代
  • reversed() 创建一个新列表,与传入的列表相反。它不会改变原始OrderedDict. 的任何方面
  • 这对我来说分别导致“dict_items 不可下标”或“dict_items 不可逆”(python 3)。我不得不这样做:for key in reversed(z.keys()): # get value using key then do stuff
  • 是的,第一个示例在 Python3 中不起作用。然而,第二个示例在 Python 3.5.2 中对我来说效果很好。 @NicholasMorley
【解决方案2】:

请注意,正如 adsmith 在 cmets 中所述,这可能是 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')])
>>> 

【讨论】:

    【解决方案3】:

    简单示例

    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
    

    【讨论】:

    • 这是用于 python 3 还是 2?
    • @CharlieParker 2
    • 为了让我工作,我必须使用 d = OrderedDict() 而不是 d = collections.OrderedDict()
    • @Csaba 取决于你的导入表单,如果你这样做 import collections 你必须这样做,否则就像示例鞋一样,OrderedDict 仅从集合中导入
    • @Pipo 是的,该代码最近被编辑并包含我的建议,但在此之前它不正确
    【解决方案4】:

    您可以使用enumerateiteritems 进行迭代:

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

    【讨论】:

    • 它适用于 python 2,但不适用于 python 3.7:AttributeError: 'collections.OrderedDict' object has no attribute 'iteritems'
    • 在 Python 3.x 中尝试使用 dict.items() 而不是 dict.iteritems()
    【解决方案5】:

    对于 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
    

    【讨论】:

      猜你喜欢
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 2013-05-18
      • 2015-09-28
      • 2022-01-18
      • 2021-01-30
      • 2021-10-29
      • 2015-09-11
      相关资源
      最近更新 更多