使用“for”循环遍历字典

Iterating over dictionaries using 'for' loops

提问人:TopChef 提问时间:7/21/2010 最后编辑:cottontailTopChef 更新时间:9/1/2023 访问量:5682676

问:

d = {'x': 1, 'y': 2, 'z': 3}

for key in d:
    print(key, 'corresponds to', d[key])

Python 如何识别它只需要从字典中读取?是一个特殊的关键字,还是只是一个变量?keykey

Python 字典

评论

0赞 Raksha Saini 1/10/2021
正如我们所知,在 Python 字典中作为一组键:值对,要求键是唯一的(在一个字典中)。一对大括号创建一个空字典:{}。在大括号内放置一个逗号分隔的键值对列表会将初始键值对添加到字典中。不,key 在 Python 中不是一个特殊的词。这里的 key 只是一个变量名。
12赞 Charlie Parker 3/17/2021
你试过吗:?for key, value in d.items():
0赞 Siva Sankar 8/2/2022
键是不可变的数据类型。密钥是唯一的。
0赞 Karl Knechtel 8/11/2022
“key 是一个特殊的关键字,还是只是一个变量?”循环语法没有这样的“特殊关键字”。请参阅了解 Python 中的循环for

答:

122赞 Alexander Gessler 7/21/2010 #1

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

要循环访问键值对,请使用以下命令:

  • for k,v in dict.iteritems()在 Python 2 中
  • for k,v in dict.items()在 Python 3 中

评论

54赞 Andreas Fester 3/26/2015
请注意,对于 Python 3,它是items()iteritems()
6812赞 sberry 7/21/2010 #2

key只是一个变量名。

for key in d:

将简单地遍历字典中的键,而不是键和值。若要遍历键和值,可以使用以下命令:

对于 Python 3.x:

for key, value in d.items():

对于 Python 2.x:

for key, value in d.iteritems():

若要自行测试,请将单词更改为 。keypoop

在 Python 3.x 中,被替换为 simple ,它返回一个由 dict 支持的类似集合的视图,类似但更好。 这在 2.7 中也可用。iteritems()items()iteritems()viewitems()

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

评论

256赞 quiet_penguin 7/28/2017
在 for 循环中添加一个被忽视的不访问值的原因:d[key] 会导致键再次被哈希处理(以获取值)。当字典很大时,这个额外的哈希值将增加总时间。Raymond Hettinger 的技术讲座 youtube.com/watch?v=anrOzOapJ2E 对此进行了讨论
9赞 JoeyC 11/8/2018
@HarisankarKrishnaSwamy有什么选择呢?
12赞 Geza Turi 7/13/2019
@yugr 为什么这么说呢?文档说 [docs.python.org/3/library/...Keys and values are iterated over in insertion order.
3赞 yugr 7/14/2019
@GezaTuri 仅从 Python 3.6 开始(并且有传言称此“功能”可能会在未来的版本中再次删除)。
26赞 Aimery 9/9/2019
@yugr 从 Python 3.7 开始,字典是按插入顺序排列的,这是一项语言功能。查看 stackoverflow.com/a/39980744/9428564
39赞 chryss 7/21/2010 #3

这是一个非常常见的循环成语。 是运算符。有关何时使用以及何时必须使用,请参阅 David Goodger 的惯用 Python 文章(存档副本)。infor key in dictfor key in dict.keys()

评论

1赞 Wolf 5/19/2016
当我读到这些部分时,运算符部分是你检查是否存在的地方。也许最好删除它是操作员信息。in
152赞 ssoler 7/21/2010 #4

key只是一个变量。

对于 Python 3.x

>>> d = {'x': 1, 'y': 2, 'z': 3}
>>> for the_key, the_value in d.items():
...     print(the_key, 'corresponds to', the_value)
...
x corresponds to 1
y corresponds to 2
z corresponds to 3

对于 Python 2.x

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

x corresponds to 1
y corresponds to 2
z corresponds to 3

...或更好,

d = {'x': 1, 'y': 2, 'z': 3} 

for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value
554赞 ars 7/21/2010 #5

并不是说key是一个特殊的词,而是字典实现了迭代器协议。你可以在课堂上这样做,例如,关于如何构建类迭代器,请参阅这个问题

就字典而言,它是在 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 dictfor x in dict.iterkeys()

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

274赞 John La Rooy 7/21/2010 #6

遍历一个键不分先后,如你所见:dict

(自 Python 3.6 以来,这种情况实际上不再存在,但请注意,自 Python 3.7 以来,它只能保证行为。

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

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

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

评论

24赞 Gregory Arenius 7/19/2018
来自 Python 3.7 发行说明:“dict 对象的插入顺序保留特性现在是 Python 语言规范的官方部分。
8赞 Neil Chowdhury o_O 1/1/2016 #7

要遍历键,速度较慢,但最好使用 .如果您尝试执行以下操作:my_dict.keys()

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

这将产生运行时错误,因为您在程序运行时更改了密钥。如果您绝对决心减少时间,请使用这种方式,但您已被警告。for key in my_dict

评论

1赞 Martijn Pieters 10/13/2020
为什么直接在字典上使用过度迭代“更好”?字典上的迭代被清楚地记录为生成键。当你回答这个问题时,你似乎想到了 Python 2,因为在 Python 3 中,在迭代过程中更改字典大小仍然会遇到同样的问题my_dict.keys()for key in my_dict.keys()
38赞 jdhao 5/25/2017 #8

我有一个用例,我必须遍历字典才能获得键、值对以及指示我所在位置的索引。我是这样做的:

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

请注意,键、值周围的括号很重要,如果没有它们,你会得到一个“没有足够的值来解压缩”。ValueError

评论

2赞 gosuto 4/13/2020
这与问题有什么关系?
32赞 Russia Must Remove Putin 6/21/2017 #9

使用“for”循环遍历字典

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

Python 如何识别它只需要从 字典?key 是 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__

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

当迭代器耗尽时,它会引发 .这就是 Python 知道退出循环、列表推导式、生成器表达式或任何其他迭代上下文的方式。一旦迭代器启动,它总是会引发它 - 如果你想再次迭代,你需要一个新的迭代器。StopIterationforStopIteration

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

如果我们想遍历这些值,我们需要使用 dicts 的方法,或者同时使用这两种方法:.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)

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

13赞 Ankur Agarwal 11/3/2017 #10

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

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

CPython dictobject.c

6赞 Amar Kumar 4/19/2020 #11

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

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)

输出:

y -> 1
z -> 2
x -> 3

评论

1赞 Joe Ferndz 12/30/2020
我不认为这是被问到的问题。问题是关于键的,以及为什么 python 在没有 .items() 或 .keys() 选项的情况下从字典中获取键。
7赞 Mister Verleg 9/9/2020 #12

如果您正在寻找一个清晰直观的例子:

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

结果:

name:  Snowy
color:  White
age:  14
-1赞 Rohit_VE 5/19/2021 #13

让我们直奔主题。如果单词 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”不是一个变量,而是一个函数。

35赞 Gowdham V 1/16/2022 #14

对于遍历字典,可以使用以下代码。

dictionary= {1: "a", 2: "b", 3: "c"}

#To iterate over the keys
for key in dictionary.keys():
    print(key)

#To Iterate over the values
for value in dictionary.values():
    print(value)

#To Iterate both the keys and values
for key, value in dictionary.items():
    print(key, '\t', value)
-1赞 theAccountant.py 1/18/2022 #15

Python 中的字典是键值对的集合。每个键都连接到一个值,您可以使用键访问与该键关联的值。键的值可以是数字、字符串、列表,甚至是其他字典。在这种情况下,将每个“键值对”作为表中的单独行进行威胁:d 是包含两列的表。key 是第一列,key[value] 是第二列。for 循环是遍历表的标准方法。

-1赞 m.r 3/25/2023 #16

当你循环一个字典时,这是实际发生的事情:

>>> d = {'x': 1, 'y': 2, 'z': 3}
>>> iter(d)
Out[408]: <dict_keyiterator at 0x2b240fc6d40>
>>> list(iter(d))
Out[409]: ['x', 'y', 'z']
>>> for key in iter(d):
        print(key)    
x
y
z
1赞 cottontail 6/17/2023 #17

如果你想遍历字典并在迭代中修改它(也许是添加/删除一个键),在 Python 2 中,可以通过循环来修改。在 Python 3 中,迭代必须基于键的显式副本(否则会抛出 ),因为返回字典键的视图,因此任何更改也会更改视图。my_dict.keys()RuntimeErrormy_dict.keys()my_dict

my_dict = {'a': 1, 'b': 2, 'c': 3}
for k in my_dict:
    my_dict.pop(k)        # <---- error


# remove keys from my_dict
for k in list(my_dict):
    my_dict.pop(k)        # <---- OK