NLP Blog

이펙티브 파이썬 - 5. 시퀀스를 슬라이스하는 방법을 알자

|

5. 시퀀스를 슬라이스하는 방법을 알자

  • 파이썬은 시퀀스를 슬라이스해서 조각으로 만드는 문법을 제공
    • 슬라이싱 대상 : list, str, bytes …
    • __getitem__, __setitem__ 매직메서드를 구현하는 클래스에서도 슬라이싱 적용 가능
  • 기본 형태 : somelist[start:end]
    • start 인덱스는 포함, end 인덱스는 제외
a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print('First four:', a[:4])
print('Last four: ', a[4:])
print('Middle two:', a[3:-3])

$$$
Fisrt four: ['a', 'b', 'c', 'd']
Last four : ['e', 'f', 'g', 'h']
Middle two: ['d', 'e']
  • 리스트 처음부터 슬라이스 할 때는 인덱스 0 생략
    • assert a[:5] == a[0:5]
  • 리스트 끝까지 슬라이스 할 때도 마지막 인덱스 생략
    • assert a[5:] == a[5:len(a)]
  • 리스트 끝을 기준으로 오프셋을 계산할 때는 음수로 계산 하는 것이 편함
    • note: 리스트의 인덱스를 음수 변수로 지정하면 슬라이싱으로 뜻밖의 결과를 얻는 몇 가지 상황 중 하나가 발생하니 주의해야 함. (ex: somelist[-n:]이라는 구문은 n>1일때는 정상 작동하지만, n=0일때 somelist[-0:] 이되면 원본 리스트의 복사본을 만듬)
  • 슬라이싱은 startend 인덱스가 리스트의 경계를 벗어나도 적절하게 처리
    • 하지만 리스트의 경계를 벗어난 인덱스를 직접 접근하면 예외가 발생

  • 슬라이싱의 결과는 완전히 새로운 리스트
    • 원본 리스트에 들어 있는 객체에 대한 참조는 유지
    • 하지만 슬라이스한 결과를 수정해도 원본 리스트에 아무런 영향을 미치지 않음
b = a[4:]
print('Before:    ', b)
b[1] = 99
print('After:     ', b)
print('No Change: ', a)

$$$
Before:   ['e', 'f', 'g', 'h']
After:    ['e', 99, 'g', 'h']
No Change:['a', 'b,' 'c,' 'd', 'e', 'f', 'g', 'h']
  • 할당에 사용하면 슬라이스는 원본 리스트에서 지정한 범위를 대체
    • a, b = c[:2]같은 튜플 할당과 달리 슬라이스 할다으이 길이는 달라도 된다.
    • 할당 받은 슬라이스의 앞뒤 값은 유지
    • 리스트는 새로 들어온 값에 맞춰 늘어나거나 줄어듦
print('Before ', a)
a[2:7] = [99, 22, 14]
print('After  ', a)

$$$
Before ['a', 'b,' 'c,' 'd', 'e', 'f', 'g', 'h']
After  ['a', 'b', 99, 22, 14, 'h']
  • 시작과 끝 인덱스를 모두 생략하고 슬라이스 하면 원본 리스트의 복사본을 얻는다
b = a[:]
assert b == a and b is not a
  • 새 리스트를 할당하지 않고 슬라이스 시작과 끝 인덱스를 지정하지 않고 할당하면 슬라이스의 전체 내용을 참조 대상의 복사본으로 대체
b = a
print('Before', a)
a[:] = [101, 102, 103]
assert a is b # 여전히 같은 리스트 객체임
print('After', a) # 이제 다른 내용을 담음

$$$
Before ['a', 'b', 99, 22, 14, 'h']
After [101, 102, 103]

핵심정리

  • 너무 장황하게 ㄴㄴ, start 인덱스에 0을 설정하거나 end 인덱스에 len(a) 이런거 ㄴㄴ
  • 슬라이싱은 범위를 벗어난 start나 end를 허용하므로 편함
  • list 슬라이스에 할당하면 원본 시퀀스에 지정한 범위를 참조 대상의 내용으로 대체 (길이가 달라도 동작)

Comments