Programing

복사본을 생성하지 않고 Python에서 목록 분할

lottogame 2020. 11. 21. 08:19
반응형

복사본을 생성하지 않고 Python에서 목록 분할


다음과 같은 문제가 있습니다.

정수의 목록을 감안할 때 L, 나는 하위 목록을 모두 생성해야 L[k:] for k in [0, len(L) - 1], 복사본을 생성하지 않고 .

파이썬에서 이것을 어떻게 수행합니까? 어떻게 든 버퍼 객체로?


짧은 대답

슬라이싱 목록은 목록에있는 개체의 복사본을 생성하지 않습니다. 단지 그들에 대한 참조를 복사합니다. 그것이 질문에 대한 대답입니다.

긴 대답

변경 가능 및 변경 불가능한 값 테스트

먼저 기본 주장을 테스트 해 봅시다. 정수와 같은 불변 객체의 경우에도 참조 만 복사됨을 보여줄 수 있습니다. 다음은 각각 동일한 값을 가진 세 가지 정수 객체입니다.

>>> a = [1000 + 1, 1000 + 1, 1000 + 1]

값은 같지만 ids 가 다르기 때문에 세 가지 별개의 객체임을 알 수 있습니다 .

>>> map(id, a)
[140502922988976, 140502922988952, 140502922988928]

슬라이스 할 때 참조는 동일하게 유지됩니다. 새 개체가 생성되지 않았습니다.

>>> b = a[1:3]
>>> map(id, b)
[140502922988952, 140502922988928]

동일한 값을 가진 다른 객체를 사용하면 복사 프로세스가 인턴에 신경 쓰지 않고 참조를 직접 복사 한다는 것을 보여줍니다 .

변경 가능한 값으로 테스트하면 동일한 결과가 나타납니다.

>>> a = [{0: 'zero', 1: 'one'}, ['foo', 'bar']]
>>> map(id, a)
[4380777000, 4380712040]
>>> map(id, a[1:]
... )
[4380712040]

남은 메모리 오버 헤드 검사

물론 참조 자체 가 복사됩니다. 각각의 비용은 64 비트 시스템에서 8 바이트입니다. 그리고 각 목록에는 72 바이트의 자체 메모리 오버 헤드가 있습니다.

>>> for i in range(len(a)):
...     x = a[:i]
...     print('len: {}'.format(len(x)))
...     print('size: {}'.format(sys.getsizeof(x)))
... 
len: 0
size: 72
len: 1
size: 80
len: 2
size: 88

Joe Pinsonault가 우리에게 상기시켜 주듯이 오버 헤드가 더해집니다. 정수 객체 자체는 그다지 크지 않습니다. 참조보다 3 배 더 큽니다. 따라서 이것은 절대적인 의미에서 약간의 메모리를 절약하지만 점근 적으로는 동일한 메모리에 "뷰"인 여러 목록을 가질 수있는 것이 좋습니다.

뷰를 사용하여 메모리 절약

불행히도, 파이썬은 목록에 "보기"인 객체를 생성하는 쉬운 방법을 제공하지 않습니다. 아니면 "다행히"라고 말해야 할 것 같습니다! 슬라이스가 어디에서 왔는지 걱정할 필요가 없습니다. 원본을 변경해도 슬라이스에는 영향을주지 않습니다. 전반적으로 이는 프로그램의 동작에 대한 추론을 훨씬 쉽게 만듭니다.

뷰로 작업하여 메모리를 절약하려면 numpy배열 사용을 고려하십시오 . numpy배열 을 슬라이스 하면 슬라이스와 원본간에 메모리가 공유됩니다.

>>> a = numpy.arange(3)
>>> a
array([0, 1, 2])
>>> b = a[1:3]
>>> b
array([1, 2])

수정 a하고 다시 보면 어떻게됩니까 b?

>>> a[2] = 1001
>>> b
array([   1, 1001])

그러나 이것은 하나의 객체를 수정할 때 실수로 다른 객체를 수정하지 않도록해야한다는 것을 의미합니다. 그것이 당신이 사용할 때의 절충점 numpy입니다. 컴퓨터 작업은 줄이고 프로그래머는 더 많은 작업을 할 수 있습니다!


수행중인 작업에 따라 islice.

반복을 통해 작동하기 때문에 새 목록을 만들지 않고 대신 yield해당 범위에 대해 요청 된대로 원래 목록의 요소를 반복자로 만듭니다 .

참고URL : https://stackoverflow.com/questions/5131538/slicing-a-list-in-python-without-generating-a-copy

반응형