2016-11-22 5 views
0

매우 어리석은 질문이지만 정말 혼란 스럽습니다. 제발 내 코드 좀 봐 :슬라이스 중첩 목록

>>> my_list = [1, 2, 3] 
>>> my_list_new = my_list[:] 
>>> my_list_new[0] = 100 
>>> my_list_new 
[100, 2, 3] 
>>> my_list 
[1, 2, 3] 

그래서 그것은해야대로 작동합니다. 나는 my_list을 복사했다. my_list_new을 변경했을 때 하나의 목록 만 변경되었습니다.

지금 이쪽을 봐 : 당신이 볼 수 있듯이

>>> my_list2 = [[1, 2, 3], [4, 5, 6]] 
>>> my_list_new2 = my_list2[:] 
>>> my_list_new2[0][0] = 100 
>>> my_list_new2 
[[100, 2, 3], [4, 5, 6]] 
>>> my_list2 
[[100, 2, 3], [4, 5, 6]] 

나는 my_list_new2을 변경하지만 두 목록이 변경되었습니다. 중첩 된 목록에 대한 일반적인 파이썬 동작입니까? 어떻게 피하는가?

+0

다음 두 가지 좋은 답변이 있습니다. 자세한 내용은 https://docs.python.org/2/library/copy.html#module-copy를 참조하십시오. 목록이 중첩 된 경우 'deepcopy'를 수행해야합니다. 그렇지 않으면 중첩 목록에 대한 참조 만 복사 됨. –

+0

레퍼런스 만 복사하는 것을 피하기 위해 슬라이스 구문을 사용해야한다는 것을 아는 것처럼 보입니다. 그래서 그 문법이없는 "복사 된"리스트, 즉 내부의 것 같은리스트가 왜 복사되었는지는 놀랍지 않습니다. 참조로. – TigerhawkT3

답변

1

my_list_new2 = [list[:] for list in my_list2] 

증명

my_list2 = [[1, 2, 3], [4, 5, 6]] 
my_list_new2 = [list[:] for list in my_list2] 
my_list_new2[0][0] = 100 

my_list_new2 
[[100, 2, 3], [4, 5, 6]] 

my_list2 
[[1, 2, 3], [4, 5, 6]] 
1

목록은 파이썬에서 변경할 수 있습니다 의도 한대로 작동합니다.

a = [1,2,3] 
b = a 
a[0] = 4 
print(b) 

당신 만 "외부"목록을 복사하고 내부 목록을 수정 중첩 된 목록의 경우 그래서 [4, 2, 3]

를 인쇄 할 것이다, 그래서 당신은뿐만 아니라 다른 목록을 수정합니다 : 의미.

my_list2 = [[1, 2, 3], [4, 5, 6]] 
my_list_new2 = [inner_lst.copy() for inner_lst in my_list2] # You can use inner_lst[:] as well 
my_list_new2[0][0] = 100 
print(my_list2) 

반환 : 당신이

솔루션이에 관심이 파이썬에서 목록 포인터를 보면 (귀하의 경우 l1 = [[1, 2, 3], [4, 5, 6]]에) [[1, 2, 3], [4, 5, 6]]

-1

목록의 개체 목록 (리스트)가 포함되어 있습니다.

목록의 조각은 객체에 참조를 삽입 목록의 부분 집합의 새로운 얕은 복사입니다. 다음 스 니펫 코드에서 볼 수 있습니다.


l1 = [[1, 2, 3], [4, 5, 6]] 
l2 = l1[:] 

print(id(l1))  # 4406414512 
print(id(l2))  # 4382080248 

# Shallow copy, insert references 
print(id(l1[0])) # 4439177768 
print(id(l2[0])) # 4439177768 

은 모든 것을 복사가 복사 객체의를 삽입 곳 copy.deepcopy을 사용합니다. my_list2이 다른 두 목록에 참조가 포함 된 외부 목록

import copy 

l1 = [[1, 2, 3], [4, 5, 6]] 
l2 = copy.deepcopy(l1) 

l2[0][0] = 100 

print(l1) # [[1, 2, 3], [4, 5, 6]] 
print(l2) # [[100, 2, 3], [4, 5, 6]] 
-1

에서 볼 수 있습니다.

외부 목록 my_list2을 독립적으로 복사하더라도 동일한 항목, 즉 동일한 두 목록에 동일한 참조가 여전히 포함됩니다 (처음에는). (C/C++에 익숙하다면, 참고 문헌리스트를 포인터로 생각할 수 있습니다.) 이것을 "얕은 사본"이라고합니다. 다음은 얕은 복사본을 만드는 몇 가지 방법입니다.

my_new_list2 = list(my_list2) 
my_new_list2 = [item for item in my_list2] 
my_new_list2 = my_list2[:] 
import copy; my_new_list2 = copy.copy(my_list2) 

원하는 동작을 얻으려면 내부 목록도 복제해야합니다.다른 사람들이 제안했듯이 직접 할 수도 있고 파이썬 표준 라이브러리가 자동으로 그렇게 할 수도 있습니다. deepcopy의 장점은 중첩, 반드시 단지 제 1 내부 수준의 수준의 임의의 수 아래의 방식으로 작동한다는 것입니다

import copy 
my_list_new2 = copy.deepcopy(my_list2) 

: 그건 copy.deepcopy가 무엇인지입니다.