使用'for'循环迭代字典

时间:2010-07-20 22:27:42

标签: python python-2.7 dictionary

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

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

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

13 个答案:

答案 0 :(得分:4763)

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)对的列表,这不会反映在{{之后发生的字典的更改1}}打电话。如果您想要3.x中的2.x行为,可以调用items()

答案 1 :(得分:385)

密钥不是一个特殊的词,但是这些词典实现了迭代器协议。你可以在课堂上做到这一点,例如请参阅this question了解如何构建类迭代器。

对于词典,它是在C级实现的。详细信息可在PEP 234中找到。特别是标题为“Dictionary Iterators”的部分:

  
      
  • 字典实现了一个返回高效的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()的缩写。

  •   

在Python 3中,不再支持dict.iterkeys()dict.itervalues()dict.iteritems()。请改用dict.keys()dict.values()dict.items()

答案 2 :(得分:182)

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

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

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 :(得分:72)

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 :(得分:49)

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

要迭代键值对,在Python 2中使用for k,v in s.iteritems(),在Python 3 for k,v in s.items()中使用。

答案 5 :(得分:26)

这是一种非常常见的循环习语。 in是运营商。何时使用for key in dict以及必须for key in dict.keys()何时使用David Goodger's Idiomatic Python article (archived copy)

答案 6 :(得分:13)

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

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

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

答案 7 :(得分:12)

  

使用'迭代字典。环

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)

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

答案 8 :(得分:7)

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

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

CPython dictobject.c

答案 9 :(得分:6)

这将按值的升序打印输出。

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)

输出:

enter image description here

答案 10 :(得分:2)

要迭代密钥,使用my_dict.keys()会更慢但更好。如果您尝试这样做:

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

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

答案 11 :(得分:2)

如果您要寻找一个清晰直观的示例:

cat  = {'name': 'Snowy', 'color': 'White' ,'age': 14}
for key , value in cat.items():
   print(key, ' : ', value)

结果:

name  :  Snowy
color  :  White
age  :  14

答案 12 :(得分:0)

让我们进入正题。如果单词 key 只是一个变量,正如您所提到的,那么主要要注意的是,当您在字典上运行 'FOR LOOP' 时,它仅通过 'keys' 并忽略 'values'

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

不如试试这个:

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

但是如果你使用这样的函数:

d = {'x': 1, 'y': 2, 'z': 3}
print(d.keys())

在上面的例子中,'keys' 不是一个变量,而是一个函数。