2017-08-22 22 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)