【问题标题】:What is the most pythonic way to iterate over OrderedDict迭代 OrderedDict 的最pythonic方法是什么
【发布时间】:2015-09-11 19:36:26
【问题描述】:

我有一个 OrderedDict,我想在循环中获取索引、键和值。 这肯定可以通过多种方式完成,即

a = collections.OrderedDict({…})
for i,b,c in zip(range(len(a)), a.iterkeys(), a.itervalues()):
  …

但我想避免 range(len(a)) 并将 a.iterkeys()、a.itervalues() 缩短为 a.iteritems() 之类的东西。 使用 enumerate 和 iteritems 可以改写为

for i,d in enumerate(a.iteritems()):
  b,c = d

但它需要在循环体内解压。 有没有办法在 for 语句中解包或者更优雅的迭代方式?

【问题讨论】:

    标签: python python-2.7 loops dictionary


    【解决方案1】:

    你可以在for statement中使用元组解包:

    for i, (key, value) in enumerate(a.iteritems()):
        # Do something with i, key, value
    

    >>> d = {'a': 'b'}
    >>> for i, (key, value) in enumerate(d.iteritems()):
    ...     print i, key, value
    ... 
    0 a b
    

    旁注:

    在 Python 3.x 中,使用 dict.items() 返回一个可迭代的字典视图。

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

    【讨论】:

    • 为什么建议使用dict.items() 代替?它实际上构造了一个新列表。
    • @farukdgn,在 Python 3.x 中,dict.items() 返回一个视图,而不是一个列表。 Python 3.x 中没有dict.iteritems。见dictionary view
    【解决方案2】:
    $ python
    Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) 
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
    Type "help", "copyright", "credits" or "license" for more information. 
    >>> import collections
    >>> a = collections.OrderedDict({'a':'1','b':'2'})
    >>> a
    OrderedDict([('a', '1'), ('b', '2')])
    >>> for i, (k,v) in enumerate(a.iteritems()):
    ...    print i, k, v
    ... 
    0 a 1
    1 b 2
    

    很丑,如果你问我的话。

    我不知道你为什么对索引感兴趣。 dict 之间的想法是你要对索引一无所知。 dict 和 queues 背后有很多逻辑,这样我们就可以摆脱索引了。

    如果您坚持获取索引,则无需迭代两次。

    让我们看看 enumerate 对列表做了什么:

    >>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']    
    >>> list(enumerate(seasons))
    [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
    >>> list(enumerate(seasons, start=1))
    [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
    

    注意“开始”。

    Enumerate 知道如何管理列表。字典将数据存储为列表,位于野兽腹部的某个地方。那么如果我们在字典上使用 enumerate 会发生什么?

    >>> for i,k in enumerate(a):
    ...    print i,k
    ... 
    0 a
    1 b
    

    在这种情况下,我会选择优雅的:

    >>> for i,k in enumerate(a):
    ...    print i,k,a[k]
    ... 
    0 a 1
    1 b 2
    

    我觉得“for i, (k,v) in”太快暴露了太多的内部结构。 有了“for i,k in”,我们就受到了保护,当需要重构时,我们不需要触及循环的方式。我们只需要改变我们在循环中所做的事情。少一个方面需要照顾。

    更不用说这个枚举调用在 2.6 之后的任何 python 中都是一样的 :)

    https://docs.python.org/2/library/stdtypes.html#dict.iteritems

    https://docs.python.org/2/library/functions.html#enumerate

    【讨论】:

    • 我需要一个索引来与知道顺序但不关心名称的组件交互。我尝试减少 [] 的数量,因为对我来说,这不仅仅是价值的字典,而是对象字典的字典,有些对象是数组,每个 [] 更多是代码中的痛苦。在某些时候,我已经将所有 iterkeys 重构为 iteritems 以缩短代码。在这种情况下使用字典列表可能更自然,但我更喜欢快速访问名称并与其他纯字典实体保持一致。
    • 对我来说,字典列表比字典字典更可取,现在这取决于您的具体情况。感觉自己有一个神物。
    【解决方案3】:

    使用valuesitems方法得到view,然后将其排版为iterator

    例如按字典中的值排序

    sorted(iter(my_dict.values()))
    

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 2013-04-12
      • 2010-09-30
      • 1970-01-01
      • 2012-11-14
      相关资源
      最近更新 更多