PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, July 10, 2022

[FIXED] Why does a = a['k'] = {} create an infinitely nested dictionary?

 July 10, 2022     assignment-operator, dictionary, operator-precedence, python, reference     No comments   

Issue

Here is my Python code that creates an infinitely nested dictionary:

a = a['k'] = {}

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

Here is the output:

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

The output shows that a['k'] refers to a itself which makes it infinitely nested.

I am guessing that the statement:

a = a['k'] = {}

is behaving like:

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

which would indeed create an infinitely nested dictionary.

I looked at Section 7.2: Assignment statements of The Python Language Reference but I couldn't find anything that implies that a = a['k'] = {} should first set a to the new dictionary and then insert a key/value pair in that dictionary. Here are some excerpts from the reference that I found relevant but did not answer my question:

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).

Each of these excerpts define the behaviour of an assignment with a single target such as a = {} and a['k'] = {} but they don't seem to talk about what should happen in case of a = a['k'] = {}. Where is the order of evaluation for such a statement documented?


This question is now resolved. GPhilo's answer pointed to the relevant clause of Section 7.2: Assignment statements. The relevant clause was right at the beginning but I had overlooked it earlier. Here it is:

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.

Let us compare it with the grammar now.

The assignment statement is defined as

assignment_stmt ::=  (target_list "=")+ (starred_expression | yield_expression)

So the statement

a = a['k'] = {}

has two target_list elements, i.e., a and a['k'], and a starred_expression element, i.e., {}, so {} is assigned to each of the target lists a and a['k'] from left to right.


Solution

Assignments in an assignment statement are resolved from left to right, as per the section 7.2 you quoted (emphasis mine):

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.

That means that yes, indeed your statement is equivalent to:

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

As a quick counter-proof, swapping the order of the assignments results in error:

a['k'] = a = {}

raises

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined


Answered By - GPhilo
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing