Python 使用“for”循环迭代字典
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3294889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Iterating over dictionaries using 'for' loops
提问by TopChef
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 keyportion. How does Python recognize that it needs only to read the key from the dictionary? Is keya special word in Python? Or is it simply a variable?
我不明白的是key部分。Python如何识别它只需要从字典中读取键?key在 Python 中是一个特殊的词吗?或者它只是一个变量?
采纳答案by sberry
keyis 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 3.x:
对于 Python 3.x:
for key, value in d.items():
For Python 2.x:
对于 Python 2.x:
for key, value in d.iteritems():
To test for yourself, change the word keyto poop.
要自己测试,请将单词更改key为poop。
In Python 3.x, iteritems()was 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()被 simple 替换items(),它返回一个由 dict 支持的类似集合的视图,就像iteritems()但更好。这也可以在 2.7 作为viewitems().
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()).
该操作items()对 2 和 3 都适用,但在 2 中它将返回字典(key, value)对的列表,这不会反映items()调用后发生的对 dict 的更改。如果您想要 3.x 中的 2.x 行为,您可以调用list(d.items()).
回答by Alexander Gessler
When you iterate through dictionaries using the for .. in ..-syntax, it always iterates over the keys (the values are accessible using dictionary[key]).
当您使用for .. in ..-syntax遍历字典时,它总是遍历键(可以使用 访问这些值dictionary[key])。
To iterate over key-value pairs, in Python 2 use for k,v in s.iteritems(), and in Python 3 for k,v in s.items().
要迭代键值对,在 Python 2 中使用for k,v in s.iteritems(),在 Python 3 中使用for k,v in s.items()。
回答by chryss
This is a very common looping idiom. inis an operator. For when to use for key in dictand when it must be for key in dict.keys()see David Goodger's Idiomatic Python article (archived copy).
这是一个非常常见的循环习语。in是一个运算符。有关何时使用for key in dict以及何时必须使用,for key in dict.keys()请参阅David Goodger 的惯用 Python 文章(存档副本)。
回答by ssoler
keyis 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)
回答by ars
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 questionfor how to build class iterators.
并不是 key 是一个特殊的词,而是字典实现了迭代器协议。你去你的班上做到这一点,例如,见这个问题对于如何建设一流的迭代器。
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
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 dictis shorthand forfor x in dict.iterkeys().
字典实现了一个 tp_iter 槽,它返回一个迭代字典键的高效迭代器。[...] 这意味着我们可以写
for k in dict: ...这相当于,但比
for k in dict.keys(): ...只要不违反对字典修改的限制(通过循环或另一个线程)。
将方法添加到显式返回不同类型迭代器的字典中:
for key in dict.iterkeys(): ... for value in dict.itervalues(): ... for key, value in dict.iteritems(): ...这意味着
for x in dict是 的简写for x in dict.iterkeys()。
In Python 3, dict.iterkeys(), dict.itervalues()and dict.iteritems()are no longer supported. Use dict.keys(), dict.values()and dict.items()instead.
在 Python 3 中,不再支持dict.iterkeys()、dict.itervalues()和dict.iteritems()。使用dict.keys(),dict.values()并dict.items()代替。
回答by John La Rooy
Iterating over a dictiterates through its keys in no particular order, as you can see here:
迭代 adict没有特定的顺序遍历它的键,正如你在这里看到的:
Edit: (This is no longer the case in Python3.6, but note that it's not guaranteedbehaviour 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 kand vautomatically:
这为您提供了一个元组列表。当你遍历他们这个样子,每个元组是解压到k和v自动:
for k,v in d.items():
print(k, 'corresponds to', v)
Using kand vas variable names when looping over a dictis 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:
如果循环体只有几行,那么在循环 a 时使用kandv作为变量名dict是很常见的。对于更复杂的循环,使用更具描述性的名称可能是个好主意:
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))
回答by Neil Chowdhury o_O
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_dictway, but you have been warned ;).
它会产生运行时错误,因为您在程序运行时更改了密钥。如果您绝对想减少时间,请使用这种for key in my_dict方式,但您已被警告;)。
回答by jdhao
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:
我有一个用例,我必须遍历 dict 以获取键、值对,以及指示我在哪里的索引。这就是我的做法:
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".
请注意,key 周围的括号,value 很重要,如果没有括号,您会收到 ValueError “没有足够的值来解包”。
回答by Aaron Hall
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?
使用“for”循环迭代字典
d = {'x': 1, 'y': 2, 'z': 3} for key in d: ...Python如何识别它只需要从字典中读取键?关键是 Python 中的一个特殊词吗?或者它只是一个变量?
It's not just forloops. The important word here is "iterating".
这不仅仅是for循环。这里的重要词是“迭代”。
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 keyis only intended to be descriptive - and it is quite apt for the purpose.
每当我们迭代它时,我们都会迭代键。变量名称key仅用于描述性 - 它非常适合此目的。
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:
>>> 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 forloop, or a list comprehension, or a generator expression, or any other iterative context. Once an iterator raises StopIterationit 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:
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 .valuesmethod of dicts, or for both together, .items:
如果我们想迭代这些值,我们需要使用.valuesdicts的方法,或者同时使用.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.
但出于学术目的,这个问题的例子很好。
回答by Ankur Agarwal
You can check the implementation of CPython's dicttypeon GitHub. This is the signature of method that implements the dict iterator:
您可以dicttype在 GitHub 上查看 CPython 的实现。这是实现 dict 迭代器的方法的签名:
_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
PyObject **pvalue, Py_hash_t *phash)

