简体   繁体   English

什么是迭代OrderedDict的最pythonic方式

[英]What is the most pythonic way to iterate over OrderedDict

I have an OrderedDict and in a loop I want to get index, key and value. 我有一个OrderedDict,在循环中我想得到索引,键和值。 It's sure can be done in multiple ways, ie 这肯定可以通过多种方式完成,即

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

But I would like to avoid range(len(a)) and shorten a.iterkeys(), a.itervalues() to something like a.iteritems(). 但我想避免范围(len(a))并将a.iterkeys(),a.itervalues()缩短为类似a.iteritems()的东西。 With enumerate and iteritems it's possible to rephrase as 使用枚举和iteritems,可以将其改写为

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

But it requires to unpack inside the loop body. 但它需要在循环体内解包。 Is there a way to unpack in a for statement or maybe a more elegant way to iterate? 有没有办法解析for语句或者更优雅的迭代方式?

You can use tuple unpacking in for statement : 您可以在for语句中使用元组解包:

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

Side Note: 边注:

In Python 3.x, use dict.items() which returns an iterable dictionary view. 在Python 3.x中,使用dict.items()返回可迭代的字典视图。

>>> for i, (key, value) in enumerate(d.items()):
...     print(i, key, value)
$ 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

Is ugly, if you ask me. 如果你问我,那很难看。

I don't know why are you interested in the index. 我不知道你为什么对索引感兴趣。 The idea between dict is that you are to be ignorant of the index. dict之间的想法是你要对索引一无所知。 There is a whole lot of logic behind dict and queues so that we are to be free of indexes. dict和队列背后有很多逻辑,所以我们要摆脱索引。

If you insist in getting the index there is no need to iterate twice. 如果你坚持获得索引,就不需要迭代两次。

Let's see what enumerate does to lists: 让我们看一下列举的枚举:

>>> 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')]

Note the "start". 注意“开始”。

Enumerate knows how to manage lists. Enumerate知道如何管理列表。 Dictionaries store data as a list, somewhere in the belly of the beast. 字典将数据存储为列表,位于野兽的腹部。 So what happens if we use enumerate on a dict? 那么如果我们在dict上使用枚举会发生什么呢?

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

In this light I would go for the elegant: 从这个角度来看,我会追求优雅:

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

I feel that "for i, (k,v) in" exposes too much of the inner structure too soon. 我觉得“对于我,(k,v)in”过早暴露了太多的内部结构。 With "for i,k in" we are protected and when times comes to refactor, we don't need to touch the way we loop. 使用“for i,k in”,我们受到保护,当重构时,我们不需要触摸循环的方式。 We need to change only what we do in the loop. 我们只需要改变我们在循环中所做的事情。 One less aspect to take care of. 少照顾一个方面。

Not to mention that this call to enumerate works just the same in any python after 2.6 :) 更不用说这个枚举的调用在2.6之后的任何python中都是一样的:)

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

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

Use the methods values or items to get a view and then typeset it as an iterator : 使用方法valuesitems来获取view ,然后将其排版为iterator

eg to sort by the values in your dictionary 例如,按字典中的值排序

sorted(iter(my_dict.values()))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM