[Python Chapter1 06]
in Python on EffectivePython
본 포스팅은
파이썬코딩의기술
이라는 책을 참고하여 개인 공부를 하면서 정리하고 있습니다.문제 될 시 삭제하겠습니다.
Chapter 1
6. 한 슬라이스에 start, end, stride를 함께 쓰지 말자
somelist[start:end:stride]
처럼 슬라이스의 간격을 설정하는 특별한 문법도 있음stride
를 이용하면 시퀀스를 슬라이스 할 때 매 n번째 아이템을 가져 올 수 있음
# stride를 쓰면 리스트에서 홀수와 짝수 인덱스를 손쉽게 그룹으로 묶을 수 있음
a = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']
odds = a[::2]
evens = a[1::2]
print(odds)
print(evens)
>>>
['red', 'yellow', 'blue']
['orange', 'greeb', 'purple']
문제는 stride
문법이 종종 예상치 못한 동작을 해서 버그를 만들어내기도 함
# 예를 들어 바이트 문자열을 역순으로 만드는 방법은 stride -1로 문자열을 슬라이스할 때
x = b'mongoose'
y = x[::-1]
print(y)
>>>
b'esoognom'
위의 코드는 바이트 문자열이나 아스키 문자에는 잘 작동하지만
UTF-8
바이트 문자열로 인코드 된 유니코드 문자에는 원하는 대로 동작하지 않음
w = '한문'
x = w.encode('utf-8')
y = x[::-1]
z = y.decode('utf-8')
>>>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb8 in
position 0: invalid start byte
# -1을 제외한 음수 값으로 stride를 지정하면 괜찮을까?
a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a[::2] # ['a', 'c', 'e', 'g']
a[::-2] # ['h', 'f', 'd'. 'b']
여기서 ::2
는 처음부터 끝까지 매 두 번째 아이템을 선택하라는 의미
::-2
는 끝부터 시작해서 반대 방향으로 매 두 번째 아이템을 선택하라는 의미
# 2::2는 무슨 뜻이며, -2::2, -2:2:-2, 2:2:-2는 어떻게 다른가?
a[2::2] # ['c', 'e', 'g']
a[-2::-2] # ['g', 'e', 'c', 'a']
a[-2:2:-2] # ['g', 'e']
a[2:2:-2] # []
위의 코드 처럼 start
, end
, stride
가 함께 쓰여지면 매우 혼란스러움
start
와 end
인덱스가 stride
와 연계되어 어떤 작용을 하는지 분명하지 않음
따라서 stride
를 start
, end
인덱스와 함께 사용하지 말아야 하고,
만약, stride
를 사용해야 한다면 양수값을 사용하고, start
와 end
는 생략
또한 stride
를 꼭 start
나 end
인덱스와 함께 사용해야 한다면 stride를 적용한 결과를 변수에 할당하고,
이 변수를 다른 변수에 할당해서 사용
b = a[::2] # ['a', 'c', 'e', 'g']
c = b[1:-1] # ['c', 'e']
정리
- 한 슬라이스에
start
,end
,stride
를 지정하면 매우 혼란스러움 - 슬라이스에
start
와end
인덱스 없이 양수stride
값을 사용 - 한 슬라이스에
start
,end
,stride
를 함께 사용하는 상황은 피하자- 꼭 사용해야 한다면
stride
를 적용한 결과를 변수에 넣고 이 변수를 다른 변수에 할당 - 내장 모듈
itertools
의islice
를 사용
- 꼭 사용해야 한다면