본문 바로가기

프로그래밍

python List 조작법 : Extended Slices

확장된 슬라이스 (Extended Slices)

Python 1.4 이후로 부터, list 를 슬라이스할때 syntax 부분에 "step" 또는 "stride" (큰걸음) 이라는 3 번째 옵션을 지원하게 되었습니다. 예를 들어 L[1:10:2],L[:-1:1],L[::-1] 와 같은 syntax를 작성하는것이 가능합니다.

이 "step" 이란것은 무슨 의미일까요? 다음 예제를 통해 바로 이해하실 수 있을겁니다.

>>> L = range(10)
>>> L[::2]
[0, 2, 4, 6, 8]

L[:][0,1,2,3,4,5,6,7,8,9] 를 가지고 있지만 2칸씩 띄어서 List를 만들고자 했으므로 L[::2] 가 되고 [0, 2, 4, 6, 8]가 되네요.

이 "step" 은 음수로도 쓸 수 있습니다. 다음은 같은 List 의 반대 방향을 가진 List 를 뽑아내는 방법입니다.

>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

step 개념은 tuple, array 그리고 string 에서도 쓸 수 있습니다.

>>> s='abcd'
>>> s[::2]
'ac'
>>> s[::-1]
'dcba'

list 또는 array 같은 mutable 한 원소들을 가지고 있는 sequence는 확장된 슬라이스를 배정하거나 지울 수 있습니다. 그런데 확장된 슬라이스와 일반적인 슬라이스를 배정하는데에는 조금 다른점이 있습니다. 일반적인 슬라이스를 배정하는것은 sequence 의 길이를 바꾸는데에도 사용됩니다.
(여기서 일반적인 슬라이스 라는 의미는 "step" 이 없는 아래 예제와 같은 자르는 방법을 이용한 개념을 말하고 확장된 슬라이스 는 "step" 을 사용한 위의 예제와 같은 자르는 방법을 이용한 개념을 말합니다.)

>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]

a[1:3][1,2] 부분인데 이것을 [4, 5, 6] 으로 배정해버렸네요. 결과적으로 바꿔치기 되므로, a[0, 4, 5, 6] 가 됩니다.

확장된 슬라이스는 유연성이 좋지 못합니다. 어떤 부분에서 그렇냐면, 확장된 슬라이스에 어떤 list를 배정한다 하면, 오른쪽 사이드에 있는 list는 반드시 바꿔치기할 원소들의 갯수와 같은 원소 개수를 가지고 있어야 합니다.

>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> a
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: attempt to assign sequence of size 3 to extended slice of size 2

a[::2][0, -1] 이라 원소 개수가 총 2개인데 [0, 1, 2] 는 원소 개수가 3개 이므로 서로 일치하지 않네요. 일반적인 슬라이스는 그냥 넣어줄텐데 여기는 "step" 개념이 추가되었기 때문에 까다로워 질 수 밖에 없습니다.

확장된 슬라이스의 삭제 부분은 좀더 직관적이죠. 따로 설명이 필요없을것이라 생각합니다.

>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> del a[::2]
>>> a
[1, 3]

built-in sequences (list, string, tuple 등등) 의 함수 __getitem__() 에다가 슬라이스한 object를 넘길 수 있습니다.

>>> range(10).__getitem__(slice(0, 5, 2))
[0, 2, 4]

range(10)[0,1,2,3,4,5,6,7,8,9] 입니다. 이것을 A 변수라 가정합시다. 그렇다면 위의 예제는 A[0:5:2] 와 같은 의미가 됩니다. 또는 아래와 같은 방식으로 가능합니다.

>>> range(10)[slice(0, 5, 2)]
[0, 2, 4]

마지막 부분은 솔직히 어디다 써야지 저렇게 활용도가 높아지게끔 쓸 수 있을까 의심이 되는군요. 아직 실력이 부족하다고 생각되는 부분입니다.

출처 : python docs