2010-03-16 3 views
0

특히, 나는 목록의 백업을 만들고, 그 목록을 약간 변경하고, 모든 변경을 세 번째 목록에 추가하고, 추가 변경을하기 전에 백업으로 첫 번째 목록을 재설정하고 싶다. m 변경이 끝나고 세 번째 목록의 모든 내용을 첫 번째 목록으로 복사하려고합니다. 불행히도 다른 함수에서 첫 번째 목록을 변경할 때마다 백업도 변경되는 것으로 보입니다. original = backup을 사용하면 너무 잘 작동하지 않습니다. 도용하지 않았다파이썬 목록에서 참조가 아닌 값만 어떻게 복사합니까?

def setEqual(restore, backup): 
    restore = [] 
    for number in backup: 
     restore.append(number) 

내 문제를 해결합니다. 백업에서 목록을 성공적으로 복원 했음에도 불구하고 원래 목록을 변경할 때마다 백업이 변경되었습니다.

어떻게이 문제를 해결할 수 있습니까?

답변

5

먼저 이해해야 할 것은 setEqual 메서드가 작동하지 않는 이유입니다. how identifiers work을 알아야합니다. (링크를 읽는 것은 매우 도움이 될 것입니다.) 너무 많은 용어가 포함 된 빠른 요약을 보려면 함수에서 매개 변수 restore이 개체에 바인딩되어 있고 해당 식별자를 = 연산자로 다시 바인딩하는 것일뿐입니다. 다음은 식별자 restore을 사물에 묶는 몇 가지 예입니다.

# Bind the identifier `restore` to the number object 1. 
restore = 1 
# Bind the identifier `restore` to the string object 'Some string.' 
# The original object that `restore` was bound to is unaffected. 
restore = 'Some string.' 

그래서, 당신이 말하는 함수에 :

restore = [] 

당신은 실제로 당신이 만드는 새로운 목록 개체 복원 바인딩된다. 파이썬은 함수 - 로컬 범위 지정을하기 때문에 예제에서 restore은 함수 로컬 식별자 restore을 새 목록에 바인딩합니다. 복원으로 setEqual으로 전달되는 내용은 변경되지 않습니다. 예를 들어,

test_variable = 1 
setEqual(test_variable, [1, 2, 3, 4]) 
# Passes, because the identifier test_variable 
# CAN'T be rebound within this scope from setEqual. 
assert test_variable == 1 

조금 단순화, 당신은 단지 현재 실행 범위에 식별자를 바인딩 할 수 있습니다 - 당신이 그 기능 이외의 범위에 영향을 def set_foo_to_bar(foo, bar) 같은 기능을 쓸 수 없다. @Ignacio에 따르면 복사 기능과 같은 것을 사용하여 현재 범위에서 식별자를 다시 바인딩 할 수 있습니다.

original = [1, 2, 3, 4] 
backup = list(original) # Make a shallow copy of the original. 
backup.remove(3) 
assert original == [1, 2, 3, 4] # It's okay! 
8

당신은 이것을 위해 copy.deepcopy()을 원합니다.

+1

이것을 사용하려면 '가져 오기 사본'을 잊지 마세요. – Morlock