2012-07-22 5 views
4

내 코드는 내가 마지막으로 인쇄가 [{'a':'b'}]이어야한다목록에 추가 된 dict을 업데이트하면 목록이 변경되는 이유는 무엇입니까?

someList = list() 
foo = {'a':'b'} 
someList.append(foo) 
print someList 
>>> [{'a':'b'}] 
defaultbazz = {'a':2, 'b':'t', 'c':'gg'} 

for k, v in defaultbazz.iteritems(): 
    foo[k] = v 

print someList 
>>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

을 think- 더 명확 할 것이다? 나는 ..

그건 나 해석의 행동을 보인다 .. 나는 그대로 원하는,

someList 업데이트하지만하지 않았다 파이썬의 작품을, 어떻게 해결 방법을 찾을 수있는 방법이라면? 심지어 새로운 딕셔너리는 원래 DICT를 업데이트 설정 ... 내 말은 : 그 일이 왜 누군가가 어쩌면 나를 설명 할 수있는 경우

someList = list() 
foo = {'a':'b'} 
someList.append(foo) 
print someList 
>>> [{'a':'b'}] 
bar = foo 
defaultbazz = {'a':2, 'b':'t', 'c':'gg'} 

for k, v in defaultbazz.iteritems(): 
    bar[k] = v 

print someList 
>>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

내가 감사 할 것입니다 ..

답변

11

그것은 당신처럼 보인다 당신의리스트가리스트에 추가되거나 새로운 변수에 할당 될 때 당신의 사전이 복사 될 것으로 기대하고 있지만 파이썬이 어떻게 작동하는지는 아닙니다. dict을 지정하면 (사실상 어떤 오브젝트를 할당해도) 새로운 오브젝트를 생성하는 것이 아니라 단순히 오브젝트에 새로운 이름을 부여하는 것입니다.

따라서 새 이름으로 개체를 편집하면 해당 개체의 단일 인스턴스가 변경되고 해당 이름으로 개체에 액세스하면 변경 내용이 표시됩니다. 당신이 당신의 객체를 복사 할 경우

, 당신은이 작업을 수행 할 수 있습니다 파이썬에서

bar = dict(foo) 

또는

bar = foo.copy() 
+0

당신과 모든 빠른 답변을 주셔서 감사합니다. – eligro

1

Dicts는 것을 의미한다 변경할 수 있습니다 그들은 바꿀 수있다. foosomeList 안에 있고 for-loopfoo이 변경 되었기 때문입니다. 이 간단한 예를 살펴 :

a_dict = {'a':'b'} 
a_list = [a_dict] 
print a_list # [{'a':'b'}] 

#change the dict 
a_dict['a'] = 'c' 
print a_list # [{'a':'c'}] 
+0

참조 전달은 완전히 다른 것입니다. (내 downvote 아니지만.) – delnan

+1

언젠가는 코멘트를 남기지 않고 뭔가를 downvote하는 것이 불가능했다면 좋겠다. 그것은 downvote 가능성이 통과 기준에 대한 언급으로 인해 것 같습니다,하지만 우리는 결코 알 수 없을 것 같아요. – kojiro

+0

그게 무슨 가치가있어, [여기 파이썬이 물건을 전달하는 방법이야] (http://stackoverflow.com/a/986145/418413). – kojiro

3

사전이 mutable 오브젝트, 스크립트의 따라서 결과입니다.

import copy 

someList.append(copy.copy(foo)) 
5

가 간소화하기 : 난 당신이 새로운 객체를 원하는 것 같아요 원래의 copy을 즉

a = {2: 3} 
b = [a] 

ba에 "참조"를 포함 (및 변경할 수있는 dict입니다) - a이 수정 된 경우 b 목록을 통해 a에 액세스하면 수정 된 a이 표시됩니다.

명시 적으로이 경우 수행 할 수 있습니다 a의 사본을 만들 필요가

:

b = [dict(a)] 

을하지만 copy.copy()copy 모듈을보고해야하며, copy.deepcopy()

2

변수 객체의 단지 이름입니다. 개체를 "첨부 된"이름으로 변경하면 다른 모든 이름의 변경 사항이 표시됩니다.파이썬은 결코 특히, 당신을 위해 자동으로 복사를 생성하지 :

someList.append(foo) 

foo의 복사본을 생성하고 someList에 넣어하지 않습니다, 그것은 이름 foo 목록에 참조하는 객체 추가합니다.

는이 개체

bar = foo 

에 대한 두 번째 이름을 만들 수 있지만이 중 복사본을 생성하지 않습니다. 특히

foo['x'] = 42 

bar['x'] = 42 

는 정확히 같은 객체를에 작동합니다. 다음과 같이 객체의 메모리 주소를 인쇄하여 확인할 수 있습니다.

print id(foo), id(bar) 

과 같은지 확인하십시오.

파이썬에서 복사본이 필요한 경우 명시 적으로 복사본을 만들어야합니다. 당신이 필요에 따라 copy 모듈은 - - copy.copy() 또는 copy.deepcopy() 중 하나는 당신이 원하는 것을 할 것입니다 :

import copy 
bar = copy.copy(foo) 
print id(foo), id(bar) 

이제 서로 다른 메모리 위치를 인쇄해야합니다.

관련 문제