참조가 아닌 값으로 파이썬리스트
이 질문에는 이미 답변이 있습니다.
- 목록을 복제하거나 복사하는 방법? 답변 15 개
예를 들어 봅시다
a=['help', 'copyright', 'credits', 'license']
b=a
b.append('XYZ')
b
['help', 'copyright', 'credits', 'license', 'XYZ']
a
['help', 'copyright', 'credits', 'license', 'XYZ']
목록 'b'에 값을 추가하고 싶었지만 목록 'a'의 값도 변경되었습니다.
나는 이것이 왜 그런지 잘 모른다고 생각합니다 (파이썬은 참조로 목록을 전달합니다).
내 질문은 " 'b'를 추가해도 'a'의 값이 변경되지 않도록 어떻게 값으로 전달할 수 있습니까?"
공식 Python FAQ 에서 대답 한 것처럼 :
b = a[:]
목록을 복사하려면 list(a)
또는 을 사용할 수 있습니다 a[:]
. 두 경우 모두 새로운 객체가 생성됩니다.
그러나이 두 가지 방법에는 내부 객체가 참조를 그대로 유지하기 때문에 변경 가능한 객체 컬렉션에 제한이 있습니다.
>>> a = [[1,2],[3],[4]]
>>> b = a[:]
>>> c = list(a)
>>> c[0].append(9)
>>> a
[[1, 2, 9], [3], [4]]
>>> c
[[1, 2, 9], [3], [4]]
>>> b
[[1, 2, 9], [3], [4]]
>>>
객체의 전체 사본을 원하면 copy.deepcopy 가 필요 합니다.
>>> from copy import deepcopy
>>> a = [[1,2],[3],[4]]
>>> b = a[:]
>>> c = deepcopy(a)
>>> c[0].append(9)
>>> a
[[1, 2], [3], [4]]
>>> b
[[1, 2], [3], [4]]
>>> c
[[1, 2, 9], [3], [4]]
>>>
성능 측면에서 내가 가장 좋아하는 대답은 다음과 같습니다.
b.extend(a)
성능 측면에서 관련 대안이 서로 어떻게 비교되는지 확인하십시오.
In [1]: import timeit
In [2]: timeit.timeit('b.extend(a)', setup='b=[];a=range(0,10)', number=100000000)
Out[2]: 9.623248100280762
In [3]: timeit.timeit('b = a[:]', setup='b=[];a=range(0,10)', number=100000000)
Out[3]: 10.84756088256836
In [4]: timeit.timeit('b = list(a)', setup='b=[];a=range(0,10)', number=100000000)
Out[4]: 21.46313500404358
In [5]: timeit.timeit('b = [elem for elem in a]', setup='b=[];a=range(0,10)', number=100000000)
Out[5]: 66.99795293807983
In [6]: timeit.timeit('for elem in a: b.append(elem)', setup='b=[];a=range(0,10)', number=100000000)
Out[6]: 67.9775960445404
In [7]: timeit.timeit('b = deepcopy(a)', setup='from copy import deepcopy; b=[];a=range(0,10)', number=100000000)
Out[7]: 1216.1108016967773
또한 다음을 수행 할 수 있습니다.
b = list(a)
이것은 인덱서와 슬라이스를 지원하지 않는 시퀀스조차도 모든 시퀀스에서 작동합니다 ...
1 차원 목록을 복사하려면
b = a[:]
그러나 a
2 차원 목록 인 경우에는 효과가 없습니다. 즉, 변경 사항 a
도에 반영됩니다 b
. 이 경우에는
b = [[a[x][y] for y in range(len(a[0]))] for x in range(len(a))]
그의 답변에서 phihag가 언급했듯이
b = a[:]
목록을 자르면 목록의 새 메모리 ID가 만들어지기 때문에 귀하의 경우에 효과적입니다 (더 이상 메모리에서 동일한 객체를 참조하지 않으며 한 변경 사항은 다른 것으로 반영되지 않음).
However, there is a slight problem. If your list is multidimensional, as in lists within lists, simply slicing will not solve this problem. Changes made in the higher dimensions, i.e. the lists within the original list, will be shared between the two.
Do not fret, there is a solution. The module copy has a nifty copying technique that takes care of this issue.
from copy import deepcopy
b = deepcopy(a)
will copy a list with a new memory id no matter how many levels of lists it contains!
To create a copy of a list do this:
b = a[:]
When you do b = a
you simply create another pointer to the same memory of a, that's why when you append to b , a changes too.
You need to create copy of a and that's done like this:
b = a[:]
I found that we can use extend() to implement the function of copy()
a=['help', 'copyright', 'credits', 'license']
b = []
b.extend(a)
b.append("XYZ")
I would recommend the following solution:
b = []
b[:] = a
This will copy all the elements from a to b. The copy will be value copy, not reference copy.
b = list(a)
See http://henry.precheur.org/python/copy_list.
참고URL : https://stackoverflow.com/questions/8744113/python-list-by-value-not-by-reference
'Programing' 카테고리의 다른 글
double을 가장 가까운 정수 값으로 어떻게 변환 할 수 있습니까? (0) | 2020.06.27 |
---|---|
요소가 포커스를 잃을 때 JavaScript 실행 (0) | 2020.06.27 |
파일에서 문자열을 nodejs로 교체 (0) | 2020.06.27 |
LINQ to SQL 왼쪽 외부 조인 (0) | 2020.06.27 |
고유 한 값을 계산하는 간단한 피벗 테이블 (0) | 2020.06.27 |