ChatGPT解决这个技术问题 Extra ChatGPT

使用“for”循环遍历字典

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

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

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

正如我们所知,在 Python 字典中作为一组键:值对,要求键是唯一的(在一个字典中)。一对大括号创建一个空字典:{}。在大括号内放置一个逗号分隔的键:值对列表会将初始键:值对添加到字典中。不,key 不是 Python 中的特殊词。这里的 key 只是一个变量名。
您是否尝试过:for key, value in d.items():

J
Jason

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() 被简单地替换为 items(),它返回一个由 dict 支持的类似集合的视图,类似于 iteritems(),但更好。这在 2.7 中也可用作 viewitems()

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


添加一个被忽略的不访问值的原因:for 循环内的 d[key] 会导致键再次被散列(以获取值)。当字典很大时,这个额外的散列会增加总时间。 Raymond Hettinger 的技术讲座 youtube.com/watch?v=anrOzOapJ2E 对此进行了讨论
@HarisankarKrishnaSwamy 什么是替代方案?
@yugr 你为什么这么说?文档说 Keys and values are iterated over in insertion order. [docs.python.org/3/library/…
@GezaTuri 仅从 Python 3.6 开始(有传言称此“功能”可能会在未来版本中再次删除)。
@yugr 从 Python 3.7 开始,字典是按插入顺序排列的,这是一种语言特性。请参阅stackoverflow.com/a/39980744/9428564
j
jpp

不是 key 是一个特殊的词,而是字典实现了迭代器协议。您可以在您的课程中执行此操作,例如,请参阅 this question 了解如何构建类迭代器。

对于字典,它是在 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()


P
Peter Mortensen

遍历 dict 会以无特定顺序遍历其键,如您在此处所见:

(这是 no longer the case in Python 3.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))

来自 Python 3.7 发行说明:“dict 对象的插入顺序保存特性现在是 Python 语言规范的官方部分。”
s
ssoler

key 只是一个变量。

对于 Python2.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

对于 Python3.X:

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

for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)

C
Chris

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

要迭代键值对,请使用以下命令:

对于 Python 2 中 dict.iteritems() 中的 k,v

对于 Python 3 中 dict.items() 中的 k,v


请注意,对于 Python 3,它是 items() 而不是 iteritems()
G
Georgy

这是一个非常常见的循环习语。 in 是一个运算符。关于何时使用 for key in dict 以及何时必须使用 for key in dict.keys(),请参阅 David Goodger's Idiomatic Python article (archived copy)


当我阅读有关 in 的这些部分时,运算符部分是 where you check for existence。也许最好删除这个 in is an operator 信息。
N
Neuron

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

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

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


这与问题有什么关系?
我不喜欢在这里使用 i。这意味着这些值以一致的顺序迭代,但事实并非如此
R
Russia Must Remove Putin

使用 '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 在许多情况下迭代。我们所看到的是,任何时候我们遍历一个字典,我们都会得到密钥。回到原来的例子:

d = {'x': 1, 'y': 2, 'z': 3} 用于输入 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)

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


G
Gowdham V

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

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)

一个直截了当的例子,代码很容易理解。谢谢你。
P
Peter Mortensen

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

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

CPython dictobject.c


N
Neuron

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

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

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


为什么使用 my_dict.keys() 而不是直接遍历字典“更好”?对字典的迭代清楚地记录为产生键。当您回答这个问题时,您似乎想到了 Python 2,因为在 Python 3 中,for key in my_dict.keys()在迭代期间更改字典大小仍然会遇到同样的问题
P
Peter Mortensen

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

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

结果:

name:  Snowy
color:  White
age:  14

N
Neuron

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

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


我不认为这是问的问题。问题是关于 key 以及为什么 python 在没有 .items() 或 .keys() 选项的情况下从字典中提取键。
R
Rohit_VE

让我们直奔主题。如果单词 key 只是一个变量,正如您所提到的,那么主要需要注意的是,当您在字典上运行“FOR LOOP”时,它只运行“键”并忽略“值”。

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' 不是一个变量,它是一个函数。


t
theAccountant.py

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