슬라이스에 증가 값까지 넣지 말기

Tasker_Jang·2026년 8월 13일
post-thumbnail

🤔 이게 왜 문제인가

파이썬은 리스트를 일정한 간격으로 건너뛰며 잘라내는 문법을 제공합니다. somelist[start:end:stride] 형태이고, 이 세 번째 값을 스트라이드(stride)라고 부릅니다. 짝수 번째 원소만 뽑거나 문자열을 뒤집을 때 x[::2], x[::-1] 한 줄이면 끝나니 처음 배울 때는 꽤 매력적으로 보입니다.

문제는 이 편리함이 시작 인덱스, 끝 인덱스와 만나는 순간부터입니다. 숫자 세 개가 대괄호 하나에 몰리면 코드 밀도가 지나치게 높아지고, 여기에 음수가 하나라도 섞이면 결과를 머릿속으로 추적하기가 사실상 불가능해집니다. 리뷰어가 "이 줄이 무엇을 반환합니까?"라고 물었을 때 작성자 본인도 인터프리터를 켜 봐야 한다면, 그 코드는 이미 버그의 온상입니다.

💣 흔한 실수

x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

# 세 자리가 다 채워지면 결과를 눈으로 예측하기 어렵습니다
print(x[2::2])     # ['c', 'e', 'g']
print(x[-2::-2])   # ['g', 'e', 'c', 'a']
print(x[-2:2:-2])  # ['g', 'e']
print(x[2:2:-2])   # []  <- 정말 의도한 결과였습니까?

# 바이트 문자열을 뒤집으면 인코딩이 깨집니다
w = '안녕'
encoded = w.encode('utf-8')
flipped = encoded[::-1]  # 문자 경계를 무시하고 바이트만 뒤집습니다

print(flipped.decode('utf-8'))  # UnicodeDecodeError

x[::-1]은 아스키 문자열에서는 잘 동작하지만, UTF-8로 인코딩된 바이트에서는 멀티바이트 문자의 내부 순서까지 뒤집어 디코딩 자체가 실패합니다. 한 줄짜리 관용구가 데이터 종류에 따라 조용히 무너지는 셈입니다.

✅ 파이썬다운 방법

from itertools import islice

x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

# 1) 스트라이드로 먼저 걸러내고
strided = x[::2]

# 2) 그 결과를 다시 슬라이스합니다
result = strided[1:-1]

print(result)  # ['c', 'e']

# 복사가 부담되는 큰 시퀀스라면 islice로 한 번에 처리합니다
lazy = list(islice(x, 2, 7, 2))  # 음수 인덱스와 음수 증가값을 아예 허용하지 않습니다

print(lazy)  # ['c', 'e', 'g']

두 단계로 나누면 한 줄이 하는 일이 하나로 줄어들어 가독성이 확실히 좋아집니다. 중간 리스트가 하나 더 생기지만 대부분의 상황에서 그 비용은 무시할 만하고, 메모리가 아깝다면 이터레이터(iterator)를 반환하는 islice가 대안이 됩니다. islice는 음수 값을 문법 차원에서 막아 주기 때문에 실수의 여지 자체를 없애 줍니다.

📎 기억할 것

  • 시작, 끝, 증가값을 한 식에 몰아넣으면 읽는 사람이 결과를 예측하기 어려워집니다.
  • 증가값을 쓸 때는 양수만 사용하고 시작·끝 인덱스는 생략하는 편이 안전합니다.
  • 세 값이 모두 필요하다면 스트라이드한 결과를 변수에 담은 뒤 다시 슬라이스합니다.
  • [::-1]은 아스키에서만 안전하며, UTF-8 바이트 문자열에서는 디코딩 오류를 냅니다.
  • 복사 비용이 부담된다면 itertools.islice를 사용합니다.

🛠 실무에서 어디 쓸까

센서 로그나 시계열 CSV를 다룰 때 "10초 간격 원본에서 30초 단위만 남기는" 다운샘플링을 자주 하게 됩니다. 이때 rows[::3][10:-10]처럼 간격과 구간을 분리해 두면 나중에 샘플링 주기만 바꾸는 수정이 훨씬 수월해집니다.

파일을 바이트로 읽어 처리하는 파서라면 data[::-1] 같은 코드를 팀 컨벤션에서 금지 목록에 올려 두는 것이 좋습니다. 테스트 데이터가 영문일 때는 멀쩡히 통과하다가 한글 데이터가 들어오는 운영 환경에서만 터지는 유형의 버그이기 때문입니다.

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글