在我的_数字键()并且修改字典中的值会使迭代器无效?

2024-04-20 10:27:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我的例子是这样的

for my_key in my_dict.keys():
    my_dict[my_key].mutate()

是否定义了上述代码的行为(假设my_dict是一个字典,mutate是一个改变其对象的方法)?我担心的是,改变字典中的值可能会使字典键上的迭代器失效。你知道吗

另一方面,keys方法的Python documentation表示它返回一个列表。如果是这样,我应该(我认为)能够变异字典的值,并且只要不变异、添加或删除任何键,就仍然可以安全地访问字典的每个元素。对吗?你知道吗


Tags: 对象方法key代码infor字典定义
3条回答

文件还说:

The values of a dictionary can be of any type, but the keys must be of an immutable data type such as strings, numbers, or tuples.

所以,你根本不能改变它们。你知道吗

是的。这并不特定于Python、字典,甚至基于散列的数据结构。你知道吗

字典的内部结构完全基于它的键。如果您更改周围的键,您可以更改字典的结构,如果这发生在直接在字典上迭代的过程中,那么迭代行为将变得未定义。具体来说,如果您想在迭代过程中添加或删除键,那么可以使用.keys()来避免实际迭代字典以避免此问题。如果你改变一个键,它就会完全被破坏,因此不允许任何可变的内置类型作为字典键。你知道吗

但是字典不关心值。它们对存储或结构没有任何影响。它们只是一个次要的细节,实现的一个微不足道的部分。它尤其不在乎你是否改变了这些值——事实上,它没有办法知道你这样做了。你知道吗

这并不奇怪。它是你迭代的关键。您按键存储东西,然后按键检索它们。您检查一个键是否是in字典,如果不是,您可能会得到一个KeyError。值就是这些紧挨着键的东西,以便在找到键时可以找到并返回它们。你知道吗

类似地,您可以迭代列表并在执行此操作时更改或替换其值,但不要追加或删除任何内容,因为这会影响内部结构。列表的索引就像它的键。你知道吗

但是,不能触摸集合的值,因为在集合中,键和值扮演相同的角色。你知道吗

是的,至少在所有基于C的Python实现中是安全的。这样做也很安全:

for my_key in my_dict: # NOTE:  no .keys() here
    my_dict[my_key].mutate()

也就是说,安全性不依赖于具体化密钥列表,通常不调用.keys()只是在密钥上迭代更有效。你知道吗

编辑

请注意,在迭代过程中完全替换与现有键关联的值也很好:

for my_key in my_dict:
    my_dict[my_key] = something_new()

文档可以更清楚地了解这一点;-)在迭代过程中删除或添加键是不安全的。你对价值观做了什么并不重要。你知道吗

相关问题 更多 >