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))))
str(a)
→"12345"
(문자열로 변환)reversed("12345")
→<reversed object>
(이터레이터 반환)map(int, reversed("12345"))
→map(int, <reversed object>)
(각 문자를 정수로 변환)list(map(...))
→[5, 4, 3, 2, 1]
(리스트 변환)
즉, 문자열을 이터레이터로 변환하여 역순을 유지한 채 정수형 리스트로 변환한다.
✅ [::-1]
사용
1
2
a = 12345
answer2 = list(map(int, str(a)))[::-1]
str(a)
→"12345"
(문자열로 변환)map(int, str(a))
→[1, 2, 3, 4, 5]
(각 문자를 정수로 변환)[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))
방식 (이터레이터)
str(a)
→ 문자열"12345"
(메모리 사용)reversed("12345")
→ 이터레이터 생성 (O(1) 메모리 사용)map(int, reversed("12345"))
→ 각 원소를 하나씩 변환 (메모리 추가 사용 없음)list(map(...))
→ 최종적으로[5, 4, 3, 2, 1]
리스트 생성 (O(n) 메모리 사용)
🟢 메모리 사용:
- 원본 문자열만 유지하고,
reversed()
는 추가적인 복사를 하지 않음. list(map(...))
을 할 때 비로소 새로운 리스트가 생성되지만, 이 과정 전까지는 메모리 절약 가능.
❌ [::-1]
방식 (새로운 리스트 생성)
str(a)
→ 문자열"12345"
(메모리 사용)map(int, str(a))
→[1, 2, 3, 4, 5]
(새로운 리스트 생성, O(n) 메모리 사용)[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()
가 더 적합하다.”