Post

reversed()와 [::-1] 메모리 효율

알고리즘 문제를 풀다가 궁금해서 알아본 파이썬 메모리 효율 정리

reversed()와 [::-1] 메모리 효율

두 코드의 차이는 reversed(str(a))이터레이터를 사용하여 역순 변환을 수행하는 방식이고, [::-1]슬라이싱을 사용하여 새로운 리스트를 생성하는 방식이라는 점이다.


1. 코드 비교

1
2
3
4
5
# 방법 1: reversed() 사용
answer1 = list(map(int, reversed(str(a))))

# 방법 2: 슬라이싱 사용
answer2 = list(map(int, str(a)))[::-1]

각 코드의 동작 과정

reversed(str(a)) 사용

1
2
a = 12345
answer1 = list(map(int, reversed(str(a))))
  1. str(a)"12345" (문자열로 변환)
  2. reversed("12345")<reversed object> (이터레이터 반환)
  3. map(int, reversed("12345"))map(int, <reversed object>) (각 문자를 정수로 변환)
  4. list(map(...))[5, 4, 3, 2, 1] (리스트 변환)

즉, 문자열을 이터레이터로 변환하여 역순을 유지한 채 정수형 리스트로 변환한다.

[::-1] 사용

1
2
a = 12345
answer2 = list(map(int, str(a)))[::-1]
  1. str(a)"12345" (문자열로 변환)
  2. map(int, str(a))[1, 2, 3, 4, 5] (각 문자를 정수로 변환)
  3. [1, 2, 3, 4, 5][::-1][5, 4, 3, 2, 1] (리스트를 역순으로 슬라이싱)

즉, 먼저 리스트를 만들고 나중에 역순으로 변환한다.


2. 차이점 정리

| 비교 항목 | reversed(str(a)) 방식 | [::-1] 방식 | |———–|—————–|—————-| | 역순 변환 시점 | 문자열에서 바로 역순 변환 | 리스트 변환 후 역순 변환 | | 메모리 효율 | ✅ 이터레이터 사용 (메모리 절약) | ❌ 새로운 리스트 생성 | | 가독성 | 다소 복잡함 | 직관적 | | 속도 | ✅ 더 빠를 수 있음 (이터레이터 활용) | ❌ 리스트를 두 번 생성 |


3. 어떤 방식을 사용할까?

  • 메모리 효율이 중요할 경우: reversed(str(a)) 방식이 유리 (이터레이터 활용).
  • 가독성이 중요한 경우: [::-1] 방식이 더 직관적.

일반적으로 큰 차이는 없지만, 리스트 크기가 커질수록 reversed() 방식이 메모리 효율적이다.

메모리가 효율적인 이유는?

reversed(str(a)) 방식이 더 메모리 효율적인 이유이터레이터(iterator)를 사용하여 원본 문자열을 복사하지 않고 역순으로 접근하기 때문이다. 반면, [::-1] 방식은 새로운 리스트를 생성하여 역순을 저장하기 때문에 더 많은 메모리를 사용한다.


1. 메모리 차이 분석

1
2
3
4
5
# 방식 1: reversed() 사용
answer1 = list(map(int, reversed(str(a))))

# 방식 2: 슬라이싱 사용
answer2 = list(map(int, str(a)))[::-1]

reversed(str(a)) 방식 (이터레이터)

  1. str(a) → 문자열 "12345" (메모리 사용)
  2. reversed("12345")이터레이터 생성 (O(1) 메모리 사용)
  3. map(int, reversed("12345"))각 원소를 하나씩 변환 (메모리 추가 사용 없음)
  4. list(map(...)) → 최종적으로 [5, 4, 3, 2, 1] 리스트 생성 (O(n) 메모리 사용)

🟢 메모리 사용:

  • 원본 문자열만 유지하고, reversed()는 추가적인 복사를 하지 않음.
  • list(map(...))을 할 때 비로소 새로운 리스트가 생성되지만, 이 과정 전까지는 메모리 절약 가능.

[::-1] 방식 (새로운 리스트 생성)

  1. str(a) → 문자열 "12345" (메모리 사용)
  2. map(int, str(a))[1, 2, 3, 4, 5] (새로운 리스트 생성, O(n) 메모리 사용)
  3. [1, 2, 3, 4, 5][::-1][5, 4, 3, 2, 1] (역순 리스트 생성, O(n) 추가 메모리 사용)

🔴 메모리 사용:

  • 기존 리스트 [1, 2, 3, 4, 5]를 먼저 생성하고, 이를 다시 복사하여 새로운 리스트 [5, 4, 3, 2, 1]을 생성하므로 총 O(2n) 메모리 사용.
  • 즉, 리스트 두 개가 한 번에 메모리에 존재해야 함.

2. 메모리 사용 비교

| 방식 | 추가 메모리 사용 | 동작 방식 | |——|—————-|———-| | reversed(str(a)) | ✅ O(n) (최종 리스트만 저장) | 원본 문자열을 그대로 사용하고, reversed()는 추가 메모리를 사용하지 않음 | | [::-1] | ❌ O(2n) (리스트 복사 발생) | 새로운 리스트를 만들고 다시 복사하여 역순 저장 |

  • reversed()메모리 사용량이 적음 (O(n)만 필요)
  • [::-1]리스트를 두 번 생성하므로 메모리 낭비가 발생 (O(2n))

3. 결론

  • 메모리 효율을 고려한다면 reversed(str(a)) 방식이 더 유리하다.
  • 속도는 큰 차이가 없지만, [::-1]는 추가적인 리스트 복사가 발생하므로 메모리를 더 사용한다.
  • 리스트 크기가 클수록 차이가 커지므로, 대용량 데이터 처리 시 reversed()를 사용하는 것이 좋다.

즉, “원본을 유지하면서 역순을 처리해야 할 경우 reversed()가 더 적합하다.”

This post is licensed under CC BY 4.0 by the author.