2017-08-22 23 views
2

我正在做一個來自LeetCode的問題。我發現了一些對我沒有多大意義的東西。在Python中通過引用和值傳遞

問題:

給定一個鏈表,每個交換兩個相鄰節點,並返回其 頭。

例如,給定1-> 2-> 3-> 4,您應該返回列表爲 2-> 1-> 4-> 3。

你的算法應該只使用恆定的空間。您不能修改列表中的 值,只有節點本身可以​​更改。

我的解決辦法:

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 

的困惑:

當我做curr = dummy,似乎假人按引用傳遞和變異curr變異dummy。但是返回語句return dummy.nextreturn curr.next的值不同?由於curr = dummy,在循環結束時,curr是在列表的末尾,所以應該不是dummy也是在列表的末尾?然而,dummy仍然在列表的最前面,dummy.next是傳遞給函數的列表的開始,但是以正確的方式變異。

而且,當我這樣做:

 if curr is dummy: 
      print("BEGIN") 

     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("END") 

BEGIN被打印,但END沒有。

有人可以幫我解決困惑嗎?

+1

'curr'最初一樣'dummy',是的,但你設置'CURR = A'內循環,所以'curr'不會和'dummy'一樣。你正在設置其他東西。在這個網站上搜索許多關於Python值/引用,變量,名稱綁定等的問題。 – BrenBarn

+0

**在Python **中沒有傳遞引用語義。 –

+3

請閱讀[Ned Batchelder關於Python名稱和值的事實和神話](https://nedbatchelder.com/text/names.html) –

回答

3

當你做任務var = x你讓var指向x。這之後不會讓其他變量指向相同的對象指向x

考慮這個例子:

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

或者這樣:

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