2016-07-20 2 views
0

클래스/객체에 대한 파이썬의 변경 가능 기능을 이해하면 할당을하면 원래 변수를 변경하면 할당 된 변수/객체도 변경된다는 것입니다. 나는이 piece of code below에 대해 혼란스러워했다.파이썬 클래스 객체의 가변성이 언제 할당에 영향을 줍니까?

# Recursive solution to Flatten Binary Tree to Linked List by LeetCode 

# Definition for a binary tree node 
# class TreeNode: 
#  def __init__(self, x): 
#   self.val = x 
#   self.left = None 
#   self.right = None 

class Solution: 
    # @param root, a tree node 
    # @return root, a tree node 
    def flattenHelper(self, root): 
     if root == None: 
      return None 
     else: 
      left = root.left 
      right = root.right 
      root.left = None # Truncate the left subtree 
      current = root 

      # Flatten the left subtree 
      current.right = self.flattenHelper(left) 
      while current.right != None: current = current.right 

      # Flatten the right subtree 
      current.right = self.flattenHelper(right) 
      return root 

    # @param root, a tree node 
    # @return nothing, do it in place 
    def flatten(self, root): 
     self.flattenHelper(root) 
     return 

질문 : 변수 left가 자동으로 root.left = NoneNone로 설정되지 않습니다 어떻게 올 실행?

+1

root.left = None은 root.left라는 이름을 None에 바인드하도록 설정합니다. 왼쪽에 묶여있는 것을 변경하지 않습니다. 그래서 노드는 어떤 것이 그것을 참조하기 때문에 존재합니다. 그것은 단지 루트입니다. 왼쪽은 더 이상 참조하지 않습니다 –

+0

@joelgoldstick 고맙습니다 만, 나는 아직도 혼란 스럽습니다 : 다음을 수행하면 : test = root, root.left = TreeNode (5), test.left .val은 이제 5가됩니다 왜 같은 일이 위에 일어나지 않습니까? – user6175310

+0

@joelgoldstick 목록의 변경 가능성과 비슷한 것이 여기 있다고 생각합니다. 만약 a = [1,2,3]이면 b = a를 정의하고, 이제는 [0] = 0, b [0] 자동으로 변경됩니다. 위의 예제와 같은 객체를 사용하여이 작업을 시도했지만 비슷한 결과가 발생했습니다. 나는이 코드의 구현에 대해 다른 점을 이해하지 못한다. 왼쪽은 None으로 자동 설정되지 않는다. – user6175310

답변

2

파이썬에서의 할당 은 항상 같은 방식으로 작동합니다.= 부호의 왼쪽에있는 것을 변경하여 오른쪽에있는 표현식의 값을 나타냅니다. 은 전혀 없습니다. "구현이 다른"의견을 물으십시오.

가끔 왼쪽의 항목이 컨테이너의 슬롯 (목록, 사전, 개체)입니다. 이 객체들은 변경 가능 (변경 가능)하므로 슬롯이 참조하는 것을 변경할 수 있습니다. 당신은 예를 들어, 수행 할 때

a = b = [0] 

이제 ab은 동일한 개체에 대한 두 개의 서로 다른 이름입니다. a[0] = 1을 입력하면 ab이 동일한 개체이므로 a이 참조하는 개체 내에서 슬롯 0에 할당하므로 할당이 변경되지 않으므로 b[0]도 1이됩니다. a 그 자체가 무엇을 의미하는지는 변경하지 않았습니다. 그러나 a = [1] 대신 b[0]ab과 다른 목록을 가리 키기 때문에 0으로 유지됩니다.

이것은 사용자의 예입니다. leftroot.left이라는 이름은 처음에는 같은 개체를 참조합니다. root.left을 다른 개체를 가리 키도록 변경하면 left이 동일한 개체를 가리 키도록 변경하지 않습니다. 그런 일이 발생하기 위해서는 left이 컨테이너 여야하며 root, 이 아닌root.left과 같은 컨테이너 여야하며 변경 될 내용은 이 아니고 left이 될 것입니다. 이름에 값을 할당하는 것 이외의 방법으로 이름의 값을 변경할 수 없기 때문입니다.

+0

감사합니다. 기본적으로 root.left를 None으로 지정하는 대신 객체에 약간의 변경이 가해 졌을 때 (예 :'root.left.left = None'), 왼쪽으로 변경됩니다 --->'left.left' 또한'None ') 이것이 맞습니까? – user6175310

+0

그런 식으로. 어림짐작은 객체 내의 슬롯 (예 :리스트 또는 사전 항목 또는 객체 속성)에 할당이있을 때만 다른 객체에 반영된 한 객체에 대한 변경을보고, 그 다음에 만 다른 참조는 동일한 포함 객체 (또는 완료 될 부모 객체)에 대한 것입니다. – kindall

+0

정말 고마워요! 당신의 모범과 설명이 너무 분명하고 도움이됩니다 !! – user6175310

관련 문제