1

Let's say I have the following names and objects

original = n = <original_object>
n = n.next = <new_object>

After running the above I would expect to see original pointing to <original_object>, but that doesn't seem to be the case.

However, if I instead do:

original = n = <original_object>
n.next = <new_object> # Attribute of the object class
n = n.next

I then see original pointing to <original_object> (or at least that's what I think I see).

Concrete example

I'll illustrate this with a linked list in Python 3.8:

class Node:
    def __init__(self, arg1):
        self.next = None

With chain assignments:

head = n = Node(None)
n = n.next = Node(None)
print(head.next) # None (the "head" is gone?)

With consecutive assignments:

head = n = Node(None) 
n.next = Node(None) # *
n = n.next # *
print(head.next) # <__main__.Node object at 0x7fa4e0610ca0>

My intention here is to preserve the "head" of the linked list as I add nodes at the tail. Why am I getting different results with chain vs consecutive assignments?

Amelio Vazquez-Reina
  • 91,494
  • 132
  • 359
  • 564
  • Does this answer your question? [How do chained assignments work?](https://stackoverflow.com/questions/7601823/how-do-chained-assignments-work) – Carcigenicate Apr 22 '20 at 23:26
  • You're assigning `n` and `n.next` to the same `Node()`, and after `n = Node()` has run. That means `head` isn't affected because `n` was reassigned first before `n.next = Node()` ran. See the top non-accepted answer. – Carcigenicate Apr 22 '20 at 23:27
  • Excellent. It does. Thanks @Carcigenicate. Good to close then. Sorry I missed that :/ – Amelio Vazquez-Reina Apr 22 '20 at 23:29
  • 2
    This is certainly an oddity of Python that bites everyone eventually, like mutable default arguments. – Carcigenicate Apr 22 '20 at 23:29

1 Answers1

0

As @Carcigenicate quickly noted, this answer explains what's happening:

In short, following that argument in my example, If I do:

n = n.next = Node(None)

that's equivalent to:

temp = Node(None)
n = temp
n.next = temp

so n gets assigned a new node before I "advance the current pointer" (n) in the linked list, whereas what I want to do is create a new node first, link to it, and then "advance the current pointer" (n) to the new node.

Amelio Vazquez-Reina
  • 91,494
  • 132
  • 359
  • 564