이번 장에서는 파이썬의 시퀀스 슬라이싱 문법을 정리한다. 슬라이싱의 대상이 되는 것은 파이썬 내장 타입인 list, str, bytes__getitem____setitem__이라는 특별한 메서드를 구현하는 파이썬의 클래스이다.

이번 포스팅은 다음의 링크를 참조하였다.

슬라이싱의 기본 문법

a = ["a", "b", "c", "d", "e", "f", "g", "h"]
print("Firts four:", a[:4])     # 리스트의 처음부터 슬라이스할 때는 인덱스 0 생략: assert a[:5] == a[0:5]
print("Last four:", a[-4:])     # 리스트의 끝까지 슬라이스 할 때는 마지막 인덱스 생략: assert a[5:] == a[5:len(a)]
print("Middle two:", a[3:-3])   # 리스트의 끝을 기준으로 오프셋 계산할 때는 음수로 슬라이스

>>>
First four: ["a", "b", "c", "d"]
First four: ["e", "f", "g", "h"]
Middle two: ["d", "e"]

슬라이싱 및 인덱싱 범위

first_twenty_items = a[:20]
last_twenty_items = a[-20:]
a[20]

>>>
IndexError: list index out of range
a[-3:]    # 제대로 동작
assert a[-0:] == a[:]

리스트의 할당

a = ["a", "b", "c", "d", "e", "f", "g", "h"]
b = a[4:]
print("Before: ", a)
print("Before: ", b)
b[1] = 99
print("After: ", a)
print("After: ", b)

>>>
Before: ["a", "b", "c", "d", "e", "f", "g", "h"]
Before: ["e", "f", "g", "h"]
After: ["a", "b", "c", "d", "e", "f", "g", "h"]
After: ["e", 99, "g", "h"]
a, b = c[:2]
a = ["a", "b", "c", "d", "e", "f", "g", "h"]
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
assert a is b                   # 같은 리스트 

Shallow copy / Deep copy

a = [1, 2, 3, 4]  # list 객체 원본
b = a             # list 객체 사본: 원본과 동일한 객체를 참조
print(b)
b[2] = 100        # b의 item 수정
print(b)
print(a)

>>>
[1, 2, 3, 4]
[1, 2, 100, 4]
[1, 2, 100, 4]    # a도 수정됨
a = 10            # 숫자 객체 원본
b = a             # 숫자 객체 사본: 원본과 동일한 객체를 참조하지 않음
print(b)
b = "abc"         # b를 수정
print(b)
print(a)

>>>
10
"abc"
10                # a는 수정되지 않음
import copy

a = [1, [1, 2, 3]]
b = copy.copy(a)        # shallow copy
print(b)
b[0] = 10
print(b)
print(a)

>>>
[1, [1, 2, 3]]
[10, [1, 2, 3]]
[1, [1, 2, 3]]          # b[0]은 immutable하기 때문에 원본/사본의 item은 서로 다른 객체
import copy

a = [1, [1, 2, 3]]
c = copy.copy(a)        # shallow copy
c[1].append(4)          # list의 두 번째 item에 4를 추가
print(c)
print(a)

>>>
[1, [1, 2, 3, 4]]
[1, [1, 2, 3, 4]]       # c[1]은 mutable하기 때문에 원본/사본의 item이 같은 객체를 참조
a = [[1, 2], [3, 4]]
b = a[:]
assert a is not b
assert a[0] is b[0]
import copy1
a = [1, [1, 2, 3]]
b = copy.deepcopy(a)    # deep copy
print(b)
b[0] = 10
b[1].append(4)
print(b)
print(a)

>>>
[10, [1, 2, 3, 4]]
[1, [1, 2, 3]]