프로그래밍파이썬 개발자

파이썬의 리스트와 튜플에서 메모리 관리자 작동 원리를 설명하십시오. 리스트와 튜플의 요소를 변경/추가하는 것의 차이점은 무엇이며, 이것이 성능에 미치는 영향은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

파이썬에서 리스트(list)는 변경 가능한 구조이고, 튜플(tuple)은 변경 불가능합니다.

  • list: 새로운 요소를 추가할 때(append, extend, insert) 파이썬은 배열의 증가 시 메모리 할당의 수를 최소화하기 위해 "여유" 메모리 블록을 할당합니다( "over-allocation strategy"). 요소를 제거할 때(pop, remove)는 빠르게 이루어지지만 가끔 메모리 재배치가 발생할 수 있습니다.
  • tuple: 튜플의 크기는 고정되어 있으며, 요소는 변경하거나 추가할 수 없습니다. 이는 불변 데이터 저장 시 읽기 작업의 속도가 빠르고 메모리 사용량이 적습니다.

리스트와 튜플의 변경 예:

lst = [1, 2, 3] lst.append(4) # 정상 lst[1] = 20 # 정상 tup = (1, 2, 3) tup[1] = 20 # TypeError

성능:

  • 리스트는 자주 변동하는 컬렉션에 적합합니다.
  • 튜플은 약간 더 빠르고 메모리 효율적입니다(고정 크기 및 해싱 원칙 덕분에), 해시 키 및 함수에서 반환되는 값(불변 데이터)에 적합합니다.

함정 질문

질문: 왜 리스트에 요소를 추가하는 작업이 일반적으로 빠르게 수행되는가(O(1))? 배열 관점에서 보면 메모리 재배치가 발생해야 하는데?

답변:

파이썬은 "여유 메모리"를 미리 할당하여 여러 요소에 대해 동적 배열을 구현합니다. 그래서 append는 보통 O(1)로 걸리며, 실제로 여유 블록이 소진될 때만 메모리 재배치가 발생합니다.

예:

import sys lst = [] for i in range(10): lst.append(i) print(len(lst), sys.getsizeof(lst)) # 메모리 크기가 엄격히 선형적으로 증가하지 않음

역사

예제 1

한 프로젝트에서 사전의 키로 list를 사용했습니다. 개발자는 리스트가 해시되지 않는다는 사실을 몰랐고, "TypeError: unhashable type: 'list'"라는 오류가 발생했습니다.


예제 2

개발자는 긴 리스트를 자주 +로 연결했기 때문에 추가적인 배열 복사 및 높은 메모리 및 시간 오버헤드가 발생했습니다. 반복문에서 append를 사용하는 것이 더 효율적이었습니다.


예제 3

로깅 시스템에서 타임스탬프를 저장하기 위해 튜플을 선택했지만, 불변성 덕분에 더 빠를 것이라고 생각했습니다. 하지만 가끔 수정이 필요하게 되어 새로운 튜플을 끊임없이 만들어야 했고(copy-on-write), 리스트를 사용하는 것보다 느려지는 원인이 되었습니다.