Jason Piao Jason Piao - 1 month ago 12
Python Question

Passing by reference and value?

Im doing a pretty simple leetcode question and got the answer, however, upon further inspection, I found something that doesn't make all that much sense to me.

The question:


Given a linked list, swap every two adjacent nodes and return its
head.

For example, Given 1->2->3->4, you should return the list as
2->1->4->3.

Your algorithm should use only constant space. You may not modify the
values in the list, only nodes itself can be changed.


My solution:

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution(object):
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""

dummy = ListNode(0)
dummy.next = head
curr = dummy

while curr.next and curr.next.next:
a = curr.next
b = curr.next.next

curr.next = b
a.next = b.next
b.next = a
curr = a


return dummy.next


The confusion:

When I do
curr = dummy
, it seems that dummy is passed by reference and mutating
curr
mutates
dummy
. But the return statement
return dummy.next
is not the same value as
return curr.next
? Since
curr = dummy
, at the end of the loop,
curr
is at the end of the list, so shouldn't
dummy
also be at the end of the list? However,
dummy
is still at the very front of the list and
dummy.next
is the start of the list passed into the function but mutated in the correct way.

Also, when I do:

if curr is dummy:
print("SS")


while curr.next and curr.next.next:
a = curr.next
b = curr.next.next

curr.next = b
a.next = b.next
b.next = a
curr = a

if curr is dummy:
print("AAA")


SS
gets printed but
AAA
doesn't.

Can someone clear the confusion up for me?

Thanks!

Answer Source

When you do an assignment var = x you make var point to x. It wouldn't make other variables pointed to the same object point to x after this.

Consider this example:

>>> a = {'p': 2}
>>> b = a
>>> b
{'p': 2}
>>> b['p'] = 4
>>> a
{'p': 4}
>>> b = {'q': 3}
>>> a
{'p': 4}
>>> b
{'q': 3}

Or this:

>>> class Node:
...     def __init__(self, nxt):
...         self.nxt = nxt
...     def __repr__(self):
...         return '(Node => %s)' % self.nxt
... 
>>> a = Node(Node(2))
>>> a
(Node => (Node => 2))
>>> b = a
>>> b
(Node => (Node => 2))
>>> a.nxt = Node(4)
>>> a
(Node => (Node => 4))
>>> b
(Node => (Node => 4))
>>> b = b.nxt
>>> a
(Node => (Node => 4))
>>> b
(Node => 4)