这是我的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'] = {}
的情况下会发生什么。记录此类声明的评估顺序在哪里?
赋值语句中的赋值从左到右解析,根据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