为什么a = a ['k'] = {}创建一个无限嵌套的字典?

问题描述 投票:8回答:1

这是我的Python代码,它创建了一个无限嵌套的字典:

a = a['k'] = {}

print(a)
print(a['k'])
print(a['k']['k'])
print(a is a['k'])

这是输出:

{'k': {...}}
{'k': {...}}
{'k': {...}}
True

输出显示a['k']指的是a本身,它使它无限嵌套。

我猜这句话:

a = a['k'] = {}

表现得像:

new = {}
a = new
a['k'] = new

这确实会创建一个无限嵌套的字典。

我查看了Python语言参考的Section 7.2: Assignment statements,但我找不到任何暗示a = a['k'] = {}应首先将a设置为新字典,然后在该字典中插入键/值对的任何内容。以下是我发现相关但没有回答我的问题的参考摘录:

如果目标列表是没有尾随逗号的单个目标,可选择在括号中,则将该对象分配给该目标。

如果目标是订阅:将评估引用中的主表达式。它应该产生可变序列对象(例如列表)或映射对象(例如字典)。接下来,评估下标表达式。

如果primary是映射对象(例如字典),则下标必须具有与映射的键类型兼容的类型,然后要求映射创建将下标映射到指定对象的键/数据对。这可以用相同的键值替换现有的键/值对,或者插入新的键/值对(如果不存在具有相同值的键)。

这些摘录中的每一个都定义了具有单个目标的赋值行为,例如a = {}a['k'] = {},但它们似乎没有谈论在a = a['k'] = {}的情况下会发生什么。记录此类声明的评估顺序在哪里?

python dictionary reference assignment-operator operator-precedence
1个回答
4
投票

赋值语句中的赋值从左到右解析,根据the section 7.2 you quoted(强调我的):

赋值语句计算表达式列表(请记住,这可以是单个表达式或以逗号分隔的列表,后者产生元组)并从左到右将单个结果对象分配给每个目标列表。

这意味着是的,确实你的陈述相当于:

new = {}
a = new
a['k'] = new

作为快速反证明,交换分配顺序会导致错误:

a['k'] = a = {}

加薪

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
© www.soinside.com 2019 - 2024. All rights reserved.