26

I need a clear explanation here. Why does the following code work ?

foo1 = foo1[0] = [0]

Ok, I know assignments are done left to right.

How does python understand foo1 is a list?

Btw I know foo1 ends up as [[...]] its first element being itself.

timgeb
  • 76,762
  • 20
  • 123
  • 145
Jeremie
  • 399
  • 4
  • 11
  • 3
    Depends on what `foo1` was originally. If looks like it was a list with at least one element in it. – Makoto Sep 23 '18 at 15:51
  • 3
    Is the question purely theoretical, or you found any use to this kind of construct? @Makoto it does not depend on the previous use / definition of `foo1`. – norok2 Sep 23 '18 at 15:55
  • 1
    @norok2: Yeah it does. You can't reference `foo1[0]` if `foo1` isn't indexable (e.g. like an object which doesn't have that property overridden or a number). – Makoto Sep 23 '18 at 16:00
  • Theoretical question. – Jeremie Sep 23 '18 at 16:01
  • 5
    @Makoto Please copy paste OP's code into a fresh interpreter session. – timgeb Sep 23 '18 at 16:17
  • Related: [Python Multiple Assignment Statements In One Line](//stackoverflow.com/q/32156515) – Aran-Fey Sep 23 '18 at 22:21
  • Also see [Simple Assignment Operator become Complicated in Python](//stackoverflow.com/q/13657704) for more shenanigans with assignments. – Martijn Pieters Sep 28 '18 at 15:12

2 Answers2

29

Because

foo1 = foo1[0] = [0]

is equivalent to

temp = [0]
foo1 = temp 
foo1[0] = temp 

it first evaluates expression and then assigns from left to right. Analyzing this line by line you'll get what's going on: - first a list is created in temp - then list temp is assigned to foo1 making it a list (answers your actual question) - 3rd line just makes an assignment of first element to the list itself (thus [[...]] in output)

Update 2: changed related question as per @blhsing comment to a more related discussion: Python Multiple Assignment Statements In One Line

Eduard
  • 897
  • 5
  • 11
  • Downvoted. While your explanation itself is correct, the doc quoted and your choice of a link to a "similar question" are completely wrong and unrelated to this question and your explanation. The citation you chose and the link you gave are in regards to an assignment of an expression list to a target list (as in `a, b = 1, 2`), whereas this question is about multiple assignments in a single statement (as in `a = b = 1`). See [Mark Dickinson's comment](https://stackoverflow.com/questions/32156515/python-multiple-assignment-statements-in-one-line) for the correct citation and reasoning. – blhsing Sep 24 '18 at 01:55
  • @blhsing, agreed. updated answer. Thanks – Eduard Sep 24 '18 at 08:44
2

Python variables know their types based on the type of variable assigned to it. It is a dynamically typed language. In your code, the interpreter sees foo1 = foo1[0] = [0] and it finds a value at the end, which is [0]. It is a list with one element 0. Now, this gets assigned to the first element of the list foo1 through foo1[0] = [0]. But since foo1 is already declared, it creates an object which has a pointer to itself, and hence foo1 gets self-referenced infinitely, with the innermost list having 0.

The structure of the list foo1 will be the same when the code is foo1 = foo1[0].

The object foo1 has entered an infinite self-referenced loop.

a_r
  • 488
  • 6
  • 12