问题:使用“ for”循环遍历字典
以下代码使我有些困惑:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print key, 'corresponds to', d[key]
我不明白的是那key
部分。Python如何识别它仅需要从字典中读取密钥?是key
Python中的特殊字?还是仅仅是一个变量?
回答 0
key
只是一个变量名。
for key in d:
只会循环遍历字典中的键,而不是键和值。要遍历键和值,可以使用以下命令:
对于Python 3.x:
for key, value in d.items():
对于Python 2.x:
for key, value in d.iteritems():
要测试自己,请将单词更改key
为poop
。
在Python 3.x中,iteritems()
替换为simple items()
,它返回由dict支持的类似set的视图,iteritems()
但效果更好。在2.7中也可用viewitems()
。
该操作items()
将对2和3都适用,但是在2中,它将返回字典(key, value)
对的列表,该列表将不反映items()
调用后发生的字典更改。如果要在3.x中使用2.x行为,可以调用list(d.items())
。
回答 1
并不是说键是一个特殊的词,而是字典实现了迭代器协议。您可以在您的类中执行此操作,例如,有关如何构建类迭代器的信息,请参见此问题。
对于字典,它是在C级别实现的。详细信息在PEP 234中可用。特别是标题为“字典迭代器”的部分:
字典实现了一个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()
。
在Python 3中dict.iterkeys()
,dict.itervalues()
和dict.iteritems()
不再受支持。使用dict.keys()
,dict.values()
并dict.items()
代替。
回答 2
遍历一个dict
通过其按键迭代没有特定的顺序,你可以在这里看到:
编辑:(在Python3.6中不再是这种情况,但是请注意,尚不能保证它的行为)
>>> d = {'x': 1, 'y': 2, 'z': 3}
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']
对于您的示例,最好使用dict.items()
:
>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]
这给您一个元组列表。当你遍历他们这个样子,每个元组是解压到k
和v
自动:
for k,v in d.items():
print(k, 'corresponds to', v)
如果循环的主体只有几行,则在遍历a时使用k
和v
作为变量名dict
非常普遍。对于更复杂的循环,最好使用更具描述性的名称:
for letter, number in d.items():
print(letter, 'corresponds to', number)
养成使用格式字符串的习惯是一个好主意:
for letter, number in d.items():
print('{0} corresponds to {1}'.format(letter, number))
回答 3
key
只是一个变量。
对于Python2.X:
d = {'x': 1, 'y': 2, 'z': 3}
for my_var in d:
print my_var, 'corresponds to', d[my_var]
… 或更好,
d = {'x': 1, 'y': 2, 'z': 3}
for the_key, the_value in d.iteritems():
print the_key, 'corresponds to', the_value
对于Python3.X:
d = {'x': 1, 'y': 2, 'z': 3}
for the_key, the_value in d.items():
print(the_key, 'corresponds to', the_value)
回答 4
当您使用for .. in ..
-syntax 遍历字典时,它总是在键上进行遍历(使用可以访问值dictionary[key]
)。
要遍历键值对,请在Python 2中使用for k,v in s.iteritems()
,在Python 3中for k,v in s.items()
。
回答 5
这是一个非常常见的循环习惯用法。in
是运算符。有关何时使用for key in dict
和何时使用的信息,for key in dict.keys()
请参阅David Goodger的Idiomatic Python文章(归档副本)。
回答 6
使用“ for”循环遍历字典
d = {'x': 1, 'y': 2, 'z': 3} for key in d: ...
Python如何识别它仅需要从字典中读取密钥?关键字在Python中是一个特殊的词吗?还是仅仅是一个变量?
不只是for
循环。这里重要的词是“迭代”。
字典是键到值的映射:
d = {'x': 1, 'y': 2, 'z': 3}
每当我们遍历它时,我们都会遍历键。变量名key
仅是描述性的,非常适合此目的。
这发生在列表理解中:
>>> [k for k in d]
['x', 'y', 'z']
当我们将字典传递到列表(或任何其他集合类型对象)时,就会发生这种情况:
>>> list(d)
['x', 'y', 'z']
Python迭代的方式是在需要的上下文中调用__iter__
对象的方法(在这种情况下为字典),该方法返回迭代器(在这种情况下为keyiterator对象):
>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>
我们不应该自己使用这些特殊方法,而是使用各自的内置函数来调用它iter
:
>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
迭代器有一个__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
当迭代器用尽时,它将引发StopIteration
。这就是Python知道退出for
循环,列表理解,生成器表达式或任何其他迭代上下文的方式。迭代器一旦引发,StopIteration
它就会一直引发-如果您想再次进行迭代,则需要一个新的迭代器。
>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']
返回字典
我们已经看到在许多情况下都会反复进行命令。我们看到的是,每当我们迭代一个字典时,我们都会得到密钥。回到原始示例:
d = {'x': 1, 'y': 2, 'z': 3} for key in d:
如果我们更改变量名,我们仍然会得到键。让我们尝试一下:
>>> for each_key in d:
... print(each_key, '=>', d[each_key])
...
x => 1
y => 2
z => 3
如果要遍历值,则需要使用.values
dicts方法,或同时使用dicts方法.items
:
>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]
在给定的示例中,迭代如下所示的项将更加有效:
for a_key, corresponding_value in d.items():
print(a_key, corresponding_value)
但是出于学术目的,这个问题的例子很好。
回答 7
我有一个用例,我必须遍历字典以获取键,值对以及指示我在哪里的索引。这是我的方法:
d = {'x': 1, 'y': 2, 'z': 3}
for i, (key, value) in enumerate(d.items()):
print(i, key, value)
请注意,键值周围的括号很重要,如果没有括号,则会出现ValueError“没有足够的值要解压”。
回答 8
您可以dicttype
在GitHub上检查CPython的实现。这是实现dict迭代器的方法的签名:
_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
PyObject **pvalue, Py_hash_t *phash)
回答 9
要遍历键,使用起来比较慢,但效果更好my_dict.keys()
。如果您尝试执行以下操作:
for key in my_dict:
my_dict[key+"-1"] = my_dict[key]-1
这将导致运行时错误,因为在程序运行时更改了密钥。如果您绝对希望减少时间,请使用此for key in my_dict
方法,但已被警告;)。
回答 10
这将按照值的升序打印输出。
d = {'x': 3, 'y': 1, 'z': 2}
def by_value(item):
return item[1]
for key, value in sorted(d.items(), key=by_value):
print(key, '->', value)
输出: