为什么 a = a['k'] = {} 创建一个无限嵌套的字典?
Why does a = a['k'] = {} create an infinitely nested dictionary?
这是我的 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
到新词典 然后 在该词典中插入一个 key/value 对。以下是我发现相关但未回答我的问题的参考资料的一些摘录:
If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target.
If the target is a subscription: The primary expression in the reference is evaluated. It should yield either a mutable sequence object (such as a list) or a mapping object (such as a dictionary). Next, the subscript expression is evaluated.
If the primary is a mapping object (such as a dictionary), the subscript must have a type compatible with the mapping’s key type, and the mapping is then asked to create a key/datum pair which maps the subscript to the assigned object. This can either replace an existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed).
这些摘录中的每一个都定义了具有单个目标(例如 a = {}
和 a['k'] = {}
的赋值行为,但它们似乎没有谈论在 [=19 的情况下应该发生什么=].在哪里记录了这种声明的评估顺序?
此问题现已解决。 的回答指向了Section 7.2: Assignment statements的相关条款。相关条款在开头是正确的,但我之前忽略了它。在这里:
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
现在让我们将其与语法进行比较。
赋值语句定义为
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
所以声明
a = a['k'] = {}
有两个 target_list
元素,即 a
和 a['k']
,以及一个 starred_expression
元素,即 {}
,所以 {}
从左到右分配给每个目标列表 a
和 a['k']
。
赋值语句中的赋值从左到右,根据the section 7.2 you quoted(强调我的):
An assignment statement evaluates the expression list (remember that
this can be a single expression or a comma-separated list, the latter
yielding a tuple) and assigns the single resulting object to each of
the target lists, from left to right.
这意味着是的,您的陈述确实等同于:
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
这是我的 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
到新词典 然后 在该词典中插入一个 key/value 对。以下是我发现相关但未回答我的问题的参考资料的一些摘录:
If the target list is a single target with no trailing comma, optionally in parentheses, the object is assigned to that target.
If the target is a subscription: The primary expression in the reference is evaluated. It should yield either a mutable sequence object (such as a list) or a mapping object (such as a dictionary). Next, the subscript expression is evaluated.
If the primary is a mapping object (such as a dictionary), the subscript must have a type compatible with the mapping’s key type, and the mapping is then asked to create a key/datum pair which maps the subscript to the assigned object. This can either replace an existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed).
这些摘录中的每一个都定义了具有单个目标(例如 a = {}
和 a['k'] = {}
的赋值行为,但它们似乎没有谈论在 [=19 的情况下应该发生什么=].在哪里记录了这种声明的评估顺序?
此问题现已解决。
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
现在让我们将其与语法进行比较。
赋值语句定义为
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
所以声明
a = a['k'] = {}
有两个 target_list
元素,即 a
和 a['k']
,以及一个 starred_expression
元素,即 {}
,所以 {}
从左到右分配给每个目标列表 a
和 a['k']
。
赋值语句中的赋值从左到右,根据the section 7.2 you quoted(强调我的):
An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.
这意味着是的,您的陈述确实等同于:
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