파이썬 코딩을 더 깔끔하게! #11

Dunno·2021년 7월 4일
0

Better Way 12. 스트라이드와 슬라이스를 한 식에 함께 사용하지 마라.

스트라이드

슬라이싱 할 때 [start : end : stride] 와 같이 시작인덱스, 끝 인덱스 외에도 일정한 간격을 두고 슬라이싱을 할 수 있는 특별한 구문을 제공한다.

  • 홀, 짝 그룹으로 나누기
x = ['빨강', '주황', '노랑', '초록', '파랑', '자주']
odds = x[::2]
evens = x[1::2]
print(odds)
print(evens)

>>>
['빨강', '노랑', '파랑']
['주황', '초록', '자주']

스트라이드의 문제점

스트라이드를 사용한 구문은 종종 예기치 못한 동작이 일어나서 버그를 야기할 수 있다. 예를 들면 문자열을 역으로 뒤집는 과정에서 오류가 발생한다.

  • bytes문자열 뒤집기
x = b'mongoose'
y = x[::-1]
print(y)

>>>
b'esoognom'
  • 유니코드 문자열 뒤집기
x = '寿司'
y = x[::-1]
print(y)

>>>
司寿

위와 같이 bytes문자열이나 유니코드 문자열은 문자열을 뒤집는 것이 가능하다 하지만 유니코드 데이터를 UTF-8로 인코딩한 문자열에서는 이 코드가 작동하지 않는다

  • UTF-8 인코딩 문자열 뒤집기
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

+) UTF-8 인코딩 문자열은 2바이트 이상으로 이루어져 있다. 그러므로 순서를 뒤집으면 기존 코드가 깨지고 이를 디코딩할 수는 없다. 단 아스키 코드에 해당하는 글자들은 모두 UTF-8로 인코딩 해도 아스키 코드와 같은 1바이트 값으로 인코딩되므로 순서를 뒤집어도 문제가 생기지 않는다.

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

>>>
'321XYZcba'

스트라이딩 후 슬라이싱하라.

  • 슬라이싱 구문에 스트라이딩까지 들어가면 읽기가 어렵다.
  • 먼저 스트라이딩을 한 후 슬라이싱을 진행해라
y = x[::2]
z = y[1:-1]
  • 스트라이딩 후 슬라이싱을 하면 데이터를 한 번 더 얕게 복사하게 된다.
  • 첫 번째 연산은 결과 슬라이스의 크기를 가능한 줄일 수 있어야 한다.
  • 프로그램이 이 두 단계 연산에 필요한 시간과 메모리를 감당할 수 없다면 itertools 내장 모듈의 islice 메서드를 고려해라.

0개의 댓글