[파이썬에서 살아남는법 제 11장] 스트라이드와 슬라이스를 한 식에 함께 사용하지 말라

2023. 2. 14. 11:43DL Study

파이썬은 리스트[시작:끝:증가값] 으로 일정한 간격을두고 슬라이싱을 할 수 있는 특별한 구문을 제공한다. 이를 스트라이드(stride) 라고 한다. 스트라이드를 사용하면 시퀀스를 슬라이싱 하면서 매 n 번째 원소만 가져올수 있다. 

x = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
odds = x[::2]
evens = x[1::2]
print(odds)
print(evens)
>>>
['red', 'yellow', 'blue']
['orange', 'green', 'purple']

하지만 스트라이드를 사용할때, 버그를 야기 할수 있다. 

예를 들어 파이썬에서 바이트 문자열을 역으로 뒤집는 가장 일반적인 기법은 -1 증가값으로 문자열을 슬라이싱 하는것이다. 

x = b'mongoose'
y = x[::-1]
print(y)
>>>
b'esoognom'

유니코드 문자열에서도 이런기법은 잘작동한다. 하지만 UTF-8로 인코딩을 하면 이 코드가 잘 작동 하지 않는다. 

 x = '壽司'
y = x[::-1]
print(y)
>>>
司壽

w = '壽司'
x = w.encode('utf-8')
y = x[::-1]
z = y.decode('utf-8')

>>>
Traceback ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in
position 0: invalid start byte
Are negative strides besides -1 useful? Consider the following
examples:

또한 -1 말고 다른 음수의 증가값에서도 유요하다. 아래 다양한 예시를 보자

x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
x[::2]     # ['a', 'c', 'e', 'g']
x[::-2]    # ['h', 'f', 'd', 'b']
x[2::2]    # ['c', 'e', 'g']
x[-2::-2]  # ['g', 'e', 'c', 'a']
x[-2:2:-2] # ['g', 'e']
x[2:2:-2]  # []

여기서 중요한점은 슬라싱 구문에 스트라이딩 까지 들어가면 정말 혼잡 스럽다는점이다.

각 괄호 안에 수가 3개나 들어있으면 코드의 밀도가 너무 높아 읽기 어렵다. 

이러한 문제를 해결하기 위해서는 시작값과 끝값을 증가값과 함께 사용하지 말것을 권장한다. 

증가값을 사용할 경우는 양수값으로 만들고 시작, 끝 인덱스를 생략하라

y = x[::2]  # ['a', 'c', 'e', 'g']
z = y[1:-1] # ['c', 'e']

스트라이딩 하고 슬라이싱을 하면 얕게 복사가 된다. 첫번째 스트라이드 구문으로 이해 리스트 슬라이스의 크기를 줄일수 있었다. 

이러한 연산을 위해 메모리가 충분하지 않다면 itertools 사용을 고려 해라 (35장)