파이썬은 리스트[시작:끝:증가값]으로 일정한 간격을 두고 슬라이싱을 할 수 있는 스트라이드를 제공한다.
x = ['빨강', '주황', '노랑', '초록', '파랑', '자주']
odds = x[::2]
evens = x[1::2]
print(odds)
print(evens)
['빨강', '노랑', '파랑'] ['주황', '초록', '자주']
스트라이드를 사용하는 구문은 버그를 야기할 수 있다.
x = b'mongoose'
y = x[::-1]
print(y)
b'esoognom'
x = '寿司'
y = x[::-1]
print(y)
司寿
유니코드 문자열에서도 잘 되지만 utf-8로 인코딩한 문자열에서는 작동되지 않는다.
w = '寿司'
x = w.encode('utf-8')
print(x)
y = x[::-1]
print(y)
z = y.decode('utf-8')
b'\xe5\xaf\xbf\xe5\x8f\xb8' b'\xb8\x8f\xe5\xbf\xaf\xe5'
--------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-4-a2081e8db6c2> in <module> 4 y = x[::-1] 5 print(y) ----> 6 z = y.decode('utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in position 0: invalid start byte
w = 'abcZYX123'
x = w.encode('utf-8')
print(x)
y = x[::-1]
print(y)
z = y.decode('utf-8')
print(z)
# 아스키 코드 범위에 포함되면 문제가 없음.
b'abcZYX123' b'321XYZcba' 321XYZcba
-1 말고 다른 음수 증가값이 유용할까?
x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
x[::2] # ['a', 'c', 'e', 'g']
x[::-2] # ['h', 'f', 'd', 'b']
['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]
[]
중요한 점은 슬라이싱 구문에 스트라이딩까지 들어가면 혼란스럽다.
이런 문제를 방지하기 위해 시작값이나 끝값을 증가값과 함께 사용하지 말자.
y = x[::2]
z = y[1:-1]
스트라이딩한 다음 슬라이싱을 하면 데이터를 한 번 더 얕게 복사하게 된다. (shallow copy)
이 두 단계 연산에 필요한 시간과 메모리를 감당할 수 없다면 itertools 내장 모듈의 isliceㄷ 메서드를 고려하자.