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()가 더 적합하다.”