提问



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


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


我不理解的是key部分.Python如何识别它只需要从字典中读取密钥?key是Python中的一个特殊单词吗?还是它只是一个变量?

最佳参考


key只是一个变量名。


for key in d:


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


对于Python 2.x:


for key, value in d.iteritems():


对于Python 3.x:


for key, value in d.items():


要自己测试,请将key改为poop


对于Python 3.x,iteritems()已被简单的items()取代,它返回由dict支持的类似集合的视图,如iteritems(),但更好。
这也可以在2.7 viewitems()中获得。


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

其它参考1


这不是一个特殊的词,但是这些词典实现了迭代器协议。你可以在你的类中执行此操作,例如,请参阅此问题以了解如何构建类迭代器。


在字典的情况下,它是在C级实现的。详细信息可在PEP 234中获得。特别是标题为字典迭代器的部分:[76]



  

      
  • 字典实现了一个返回高效的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 dictfor x in dict.iterkeys()的简写。

  •   


其它参考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)]


这为您提供了元组列表。当你像这样循环它们时,每个元组会自动解压缩到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))

其它参考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 .. - 语法迭代字典时,它总是遍历键(可以使用dictionary[key]访问这些值)。


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

其它参考5


这是一个非常常见的循环习语。 in是一名运营商。何时使用for key in dict以及何时for key in dict.keys()请参阅David Goodger的惯用Python文章。[78]

其它参考6


你可以用这个:


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

其它参考7


我有一个用例,我必须遍历dict以获取键,值对,以及指示我在哪里的索引。我是这样做的:


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


请注意,键周围的括号值很重要,如果没有括号,则会得到ValueError没有足够的值来解包。

其它参考8



  

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


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

其它参考9


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


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


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

其它参考10


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


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


CPython dictobject.c [79]