python遍历字典 - python遍历数组




使用'for'循环迭代字典 (8)

我对以下代码感到有点困惑:

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

我不明白的是key部分。 Python如何识别它只需要从字典中读取密钥? key是Python中的一个特殊词吗? 或者它只是一个变量?


使用'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']

回到dicts

我们已经看到dicts在许多情况下迭代。 我们所看到的是,无论何时我们迭代dict,我们都会得到密钥。 回到原始示例:

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方法,或者同时使用.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)

但是出于学术目的,问题的例子很好。


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)

你可以用这个:

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

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

这为您提供了元组列表。 当你像这样循环它们时,每个元组都自动解压缩为kv

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

如果循环的主体只有几行,则在循环dict时使用kv作为变量名是很常见的。 对于更复杂的循环,使用更具描述性的名称可能是个好主意:

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

当您使用for .. in .. -syntax迭代字典时,它总是遍历键(可以使用dictionary[key]访问这些值)。

要迭代键值对,请for k,v in s.iteritems()使用for k,v in s.iteritems()


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

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

CPython dictobject.c


要迭代键,使用my_dict.keys()会更慢但更好。 如果您尝试执行以下操作:

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

它会产生运行时错误,因为您在程序运行时更改了键。 如果您绝对准备减少时间,请for key in my_dict方式使用for key in my_dict ,但您已收到警告;)。


这是一个非常常见的循环习语。 in是一个运营商。 关于何时使用for key in dict以及何时必须使用for key in dict.keys()请参阅David Goodger的Idiomatic Python文章





dictionary