遍历使用“for”循环的字典。

[英]Iterating over dictionaries using 'for' loops


I am a bit puzzled by the following code:

下面的代码让我有点困惑:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

What I don't understand is the key portion. How does Python recognize that it needs only to read the key from the dictionary? Is key a special word in Python? Or is it simply a variable?

我不明白的是关键部分。Python如何识别它只需要从字典中读取键?在Python中,key是一个特殊的词吗?还是仅仅是一个变量?

11 个解决方案

#1


3655  

key is just a variable name.

key只是一个变量名。

for key in d:

will simply loop over the keys in the dictionary, rather than the keys and values. To loop over both key and value you can use the following:

将简单地循环字典中的键,而不是键和值。要对键和值进行循环,可以使用以下内容:

For Python 2.x:

对于Python 2. x:

for key, value in d.iteritems():

For Python 3.x:

对于Python 3. x:

for key, value in d.items():

To test for yourself, change the word key to poop.

为了测试你自己,把单词key改成便便。

For Python 3.x, iteritems() has been replaced with simply items(), which returns a set-like view backed by the dict, like iteritems() but even better. This is also available in 2.7 as viewitems().

Python 3。x, iteritems()已经被简单的items()替换,它返回由dict语句支持的类集视图,比如iteritems(),但是更好。这也可以作为viewitems()的2.7。

The operation items() will work for both 2 and 3, but in 2 it will return a list of the dictionary's (key, value) pairs, which will not reflect changes to the dict that happen after the items() call. If you want the 2.x behavior in 3.x, you can call list(d.items()).

操作项()将同时适用于2和3,但在2中,它将返回字典(key, value)对的列表,它不会反映在items()调用之后发生的改变。如果你想要2。x行为3。可以调用list(d.items())。

#2


319  

It's not that key is a special word, but that dictionaries implement the iterator protocol. You could do this in your class, e.g. see this question for how to build class iterators.

不是这个键是一个特殊的词,而是字典实现了迭代器协议。您可以在您的类中这样做,例如,关于如何构建类迭代器,请参见这个问题。

In the case of dictionaries, it's implemented at the C level. The details are available in PEP 234. In particular, the section titled "Dictionary Iterators":

对于字典来说,它是在C级实现的。详细信息请参阅PEP 234。特别是题为“字典迭代器”的一节:

  • Dictionaries implement a tp_iter slot that returns an efficient iterator that iterates over the keys of the dictionary. [...] This means that we can write

    字典实现一个tp_iter插槽,该插槽返回一个高效的迭代器,该迭代器遍历字典的键。[…这意味着我们可以写作

    for k in dict: ...
    

    which is equivalent to, but much faster than

    这是等价的,但比

    for k in dict.keys(): ...
    

    as long as the restriction on modifications to the dictionary (either by the loop or by another thread) are not violated.

    只要不违反对字典修改的限制(无论是由循环还是由另一个线程)。

  • Add methods to dictionaries that return different kinds of iterators explicitly:

    向明确返回不同类型迭代器的字典添加方法:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    This means that for x in dict is shorthand for for x in dict.iterkeys().

    这意味着,在dict中的x是dict.iterkeys()中的x的简写。

#3


147  

Iterating over a dict iterates through its keys in no particular order, as you can see here:

遍历一个命令遍历它的键,没有特定的顺序,正如您在这里看到的:

Edit: (This is no longer the case in Python3.6, but note that it's not guaranteed behaviour yet)

编辑:(在Python3.6中已经不是这样了,但是注意它还没有保证行为)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

For your example, it is a better idea to use dict.items():

对于您的示例,最好使用dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

This gives you a list of tuples. When you loop over them like this, each tuple is unpacked into k and v automatically:

这将给您一个元组列表。当你像这样对它们进行循环时,每个元组会自动地解压缩到k和v中:

for k,v in d.items():
    print(k, 'corresponds to', v)

Using k and v as variable names when looping over a dict is quite common if the body of the loop is only a few lines. For more complicated loops it may be a good idea to use more descriptive names:

当循环遍历一个命令时,如果循环的主体只有几行,那么使用k和v作为变量名是很常见的。对于更复杂的循环,最好使用更多的描述性名称:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

It's a good idea to get into the habit of using format strings:

养成使用格式字符串的习惯是个好主意:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))

#4


41  

key is simply a variable.

key只是一个变量。

For Python2.X:

Python2.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... or better,

…或更好,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

For Python3.X:

Python3.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

#5


38  

When you iterate through dictionaries using the for .. in ..-syntax, it always iterates over the keys (the values are accessible using dictionary[key]).

当你使用for循环遍历字典时。在. .-语法,它总是遍历键(值可以使用dictionary[key]访问)。

To iterate over key-value pairs, use for k,v in s.iteritems().

要迭代键-值对,可以在.iteritems()中使用k和v。

#6


19  

This is a very common looping idiom. in is an operator. For when to use for key in dict and when it must be for key in dict.keys() see David Goodger's Idiomatic Python article.

这是一个非常常见的循环语句。是一个操作符。关于何时在dict类型中使用key和何时必须在dict.keys()中使用key,请参阅David Goodger的惯用Python文章。

#7


8  

You can use this:

您可以使用:

for key,val in d.items():
    print key, 'is the key for ', val

#8


4  

I have a use case where I have to iterate through the dict to get the key, value pair, also the index indicating where I am. This is how I do it:

我有一个用例,在这个用例中,我必须遍历该命令以获取键值对,以及指示我所在位置的索引。我是这样做的:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

Note that the parentheses around the key, value is important, without the parentheses, you get an ValueError "not enough values to unpack".

注意,键周围的圆括号,值很重要,如果没有圆括号,就会得到一个ValueError“值不够解包”。

#9


3  

Iterating over dictionaries using 'for' loops

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

How does Python recognize that it needs only to read the key from the dictionary? Is key a special word in Python? Or is it simply a variable?

Python如何识别它只需要从字典中读取键?在Python中,key是一个特殊的词吗?还是仅仅是一个变量?

It's not just for loops. The important word here is "iterating".

它不只是循环。这里的关键词是“迭代”。

A dictionary is a mapping of keys to values:

字典是键与值的映射:

d = {'x': 1, 'y': 2, 'z': 3} 

Any time we iterate over it, we iterate over the keys. The variable name key is only intended to be descriptive - and it is quite apt for the purpose.

每次迭代它时,我们都会遍历键。变量名键仅用于描述性——它非常适合用于此目的。

This happens in a list comprehension:

这发生在列表理解中:

>>> [k for k in d]
['x', 'y', 'z']

It happens when we pass the dictionary to list (or any other collection type object):

当我们将字典传递给列表(或任何其他集合类型对象)时,它会发生:

>>> list(d)
['x', 'y', 'z']

The way Python iterates is, in a context where it needs to, it calls the __iter__ method of the object (in this case the dictionary) which returns an iterator (in this case, a keyiterator object):

Python的迭代方式是,在需要的上下文中,它调用对象的__iter__方法(在本例中是字典),该方法返回迭代器(在本例中是keyiterator对象):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

We shouldn't use these special methods ourselves, instead, use the respective builtin function to call it, iter:

我们不应该自己使用这些特殊的方法,而是使用各自的内建函数来调用它,iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

Iterators have a __next__ method - but we call it with the builtin function, next:

迭代器有一个__next__方法——但是我们用内建函数调用它,然后:

>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

When an iterator is exhausted, it raises StopIteration. This is how Python knows to exit a for loop, or a list comprehension, or a generator expression, or any other iterative context. Once an iterator raises StopIteration it will always raise it - if you want to iterate again, you need a new one.

当迭代器耗尽时,将引发StopIteration。这就是Python知道如何退出for循环、列表理解、生成器表达式或任何其他迭代上下文的原因。一旦迭代器引发StopIteration,它总是会引发它——如果你想再次迭代,你需要一个新的迭代。

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

Returning to dicts

We've seen dicts iterating in many contexts. What we've seen is that any time we iterate over a dict, we get the keys. Back to the original example:

我们已经在许多上下文中看到了dicts迭代。我们所看到的是,每当我们遍历一条法令,我们就会得到钥匙。回到原始示例:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:

If we change the variable name, we still get the keys. Let's try it:

如果我们改变变量名,我们仍然得到键。让我们试一试:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

If we want to iterate over the values, we need to use the .values method of dicts, or for both together, .items:

如果我们想要迭代这些值,我们需要使用dicts的.values方法,或者同时使用.items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

In the example given, it would be more efficient to iterate over the items like this:

在给定的示例中,迭代这样的项会更有效:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

But for academic purposes, the question's example is just fine.

但就学术而言,这个问题的例子还不错。

#10


1  

To iterate over keys, it is slower but better to use my_dict.keys(). If you tried to do something like this:

要遍历键,使用my_dict.keys()会更慢,但效果更好。如果你想做这样的事情:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

it would create a runtime error because you are changing the keys while the program is running. If you are absolutely set on reducing time, use the for key in my_dict way, but you have been warned ;).

它将创建一个运行时错误,因为您正在更改程序运行时的密钥。如果您已经确定要减少时间,请在my_dict方法中使用for键,但是您已经得到警告;)

#11


1  

You can check the implementation of CPython's dicttype on GitHub. This is the signature of method that implements the dict iterator:

您可以在GitHub上检查CPython的dicttype的实现。这是实现dict迭代器的方法的签名:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c

CPython dictobject.c

关注微信公众号

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2010/07/20/887e1fa0ee8b5e4706ef12b64a9d7559.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com