Неожиданный обход дерева результатов — Python

#python #tree #tree-traversal

#python #дерево #обход дерева

Вопрос:

У меня есть неожиданный результат, в котором значения self.path и self.path_temp различны, и единственный способ, которым они отличаются, заключается в том, что одно обновляется строкой, а другое списком, все они передаются через функцию trav в качестве аргументов. Являются ли списки каким-либо образом постоянными в памяти в python? Правильное или подробное объяснение было бы оценено!

PS: Правильным является тот, self.path который обновляется с помощью строки.

 
    def binaryTreePaths(self, root: TreeNode) -> List[str]:
                
        self.path = []
        temp = []
        self.path_temp = []

        
        def trav(root,path,temp):
            
            if root:
                
                path  = str(root.val)
                temp.append(root.val)

                if root.right == None and root.left==None:
                    self.path.append('->'.join(path))
                    self.path_temp.append('->'.join(temp))
                
                    
                trav(root.left,path,temp)
                trav(root.right,path,temp)
        
        
        trav(root,'',temp)    
        print(self.path)
        print(self.path_temp)

  

Комментарии:

1. Что такое ls ???

2. Моя ошибка, это должно было быть временным. Но это была опечатка, когда я менял имена переменных. Это не меняет проблему функционально

Ответ №1:

Разница в том, что path это примитивное значение (строка), а temp нет. Когда вы делаете

 path  = str(root.val) 
  

На самом деле вы создаете новую строку. Строки неизменяемы в Python. Кроме того, вызывающая функция не увидит никаких изменений в path переменной, которую она передала в качестве аргумента.

С temp это другая история. Когда вы делаете

 temp.append(root.val)
  

… вы изменяете temp список. Это список, который вызывающий объект передал в качестве аргумента, и поэтому список вызывающего объекта видоизменяется этим действием. Во всех рекурсивных процессах существует несколько temp экземпляров переменных, но все они ссылаются на один и тот же список. Каждый из них append влияет на все temp экземпляры переменных.

Если вы хотите, чтобы temp поведение было подобным path , тогда вы должны создать новый список вместо изменения существующего:

 temp = temp   [root.val]
  

ПРИМЕЧАНИЕ: не сокращайте это до temp = [root.val] , так как тогда вы снова отключаете исходный список.