코딩테스트 공부를 하던 중 많이 시퀀스 자료형의 슬라이스라는 기능이 자주 사용되어서 한번 정리하고자 한다.
슬라이스의 뜻은 무엇인가의 일부를 잘라낸다는 뜻을 가지고 있다.
여기서도 같은 의미로 시퀀스 객체의 일부를 잘라낸다는 의미이다.
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[0:4]
#output
[0, 10, 20, 30]
위의 코드 처럼 [ ] 안에 시작:끝 인덱스를 지정하게 되면 지정한 범위의 리스트를 잘라서 가져오는 것이 가능하다.
🚨 끝 인덱스는 가져오는 범위에 속하지 않는다는 것을 주의해야한다. 실제로 끝의 값을 생각해서 가져오기 위해서는 1을 더 크게 지정해야 한다.
리스트에서 n번째 부분을 가져오는 방법은 아래와 같다. (ex: n=4)
#인덱스의 4부터 6까지 요소 3개 가져오기
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[4:7]
#output
[40, 50, 60]
슬라이스는 a[4:-1] 과 같이 음수를 인덱스로 지정할 수도 있다.
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[4:-1]
#output
[40, 50, 60, 70, 80]
인덱스에서 -1 은 뒤에서 첫 번째 요소를 뜻한다. 음수도 마찬가지로 끝 인덱스는 가져오려는 인덱스보다 1을 더 크게 지정하기 때문에 인덱스 -2의 요소인 80까지만 가져오게 되는 것이다.
인덱스의 증가폭을 지정해서 인덱스를 건너뛰어서 인덱스를 가져올 수도 있다.
#인덱스 2부터 7까지 가져오는데 3씩 증가시키면서 가져오기
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[2:8:3]
#output
[20, 50]
시작 인덱스가 2이므로 20부터 가져오고 증가폭을 3으로 지정했기 때문에 50을 가져올 수 있다. (80을 주의하자.)
슬라이스는 인덱스를 생략하는 것도 가능하다.
시퀀스 객체의 길이를 몰라도 되기 때문에 자주 쓰이는 방식이다.
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[:7]
#output
[0, 10, 20, 30, 40, 50, 60]
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[7:]
#output
[70, 80, 90]
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[0:len(a)]
a[:len(a)]
#output a[0:len(a)], a[:len(a)] 같음
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
파이썬은 tuple, range, 문자열도 시퀀스 자료형이기 때문에 리스트와 같은 방식으로 슬라이스를 사용할 수 있다.
다음은 지정된 범위 만큼 tuple을 잘라서 새 tuple을 만든다.
#input
a = (0, 10, 20, 30, 40, 50, 60, 70, 80, 90)
a[4:7]
#output: (40, 50, 60)
a[4:]
#output: (40, 50, 60, 70, 80, 90)
a[:7:2]
#output: (0, 20, 40, 60)
range는 연속된 숫자를 생성한다. range에 슬라이스를 사용하게 되면 지정된 범위의 숫자를 생성하는 range 객체를 새로 만들게 된다.
#input
a = range(10)
a
#output: range(0, 10)
a[4:7]
#output: range(4, 7)
a[4:]
#output: range(4, 10)
a[:7:2]
#output: range(0, 7, 2)
range는 리스트, 튜플과는 달리 요소가 모듀 표시되지 않고 생성 범위만 표시되게 되는데 리스트로 만들기 위해서는 list를 사용하면 된다.
#input
list(a[:7:2])
#output: [0, 20, 40, 60]
문자열도 마찬가지로 시퀀스 자료형이므로 슬라이스를 사용할 수 있는데,
문자열은 문자 하나가 요소이므로 문자 단위로 잘라 새 문자열을 만들게 된다.
#input
wel = 'Welcome, IToriginal!"
wel[2:9]
#output: 'lcome, '
wel[2:]
#output: 'lcome, IToriginal'
wel[:9:2]
#output: 'Wloe '
시퀀스 객체는 슬라이스로 범위를 지정해 여러 요소에 값을 할당하는 것이 가능하다.
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
a[2:5] = ['a', 'b', 'c']
a
#output: [0, 10, 'a', 'b', 'c', 50, 60, 70, 80 ,90]
a[2:5] = ['a', 'b', 'c'] 와 같이 리스트에 범위를 지정하고 다른 리스트를 할당하였다. 이런 경우 인덱스 2부터 4까지 문자 'a', 'b', 'c' 가 들어간다. 특히 이렇게 범위를 지정해서 요소를 할당하게 되면 원래 기존의 리스트가 변경 되어서 새 리스트는 생성되지 않는다.
a[2:5] = ['a', 'b', 'c'] 의 경우,
슬라이스의 범위와 할당할 리스트의 요소 개수를 정확히 맞추었지만, 갯수를 맞추지 않아도 상관없다.
a[2:5] = ['a'] 라고 주어졌을 때,
output은 [0, 10, 'a', 50, 60, 70, 80, 90] 이 출력되게 된다.
반면에, 요소 개수가 많으면 그 만큼 리스트의 요소 개수도 늘어난다.
마찬가지로, 인덱스 증가폭을 지정하면 증가폭의 값 만큼 요소가 할당하게 된다.
단, 인덱스 증가폭을 지정하게 되었을 경우에는 슬라이스 범위의 요소 개수와 할당할 요소 개수가 정확히 일치해야 한다.
🚨 tuple, range, 문자열은 슬라이스 범위를 지정하더라도 요소를 할당할 수 없다.
슬라이스 삭제는 다음과 같이 del 뒤에 삭제할 범위를 지정해주면 된다.
#input
a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
del a[2:5]
a #output: [0, 10, 50, 60, 70, 80, 90]
b = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
del b[2:8:2]
b #output: [0, 10, 30, 50, 70, 80, 90]
del을 사용하여 요소를 삭제한 경우 원래 있던 리스트가 변경되어 새 리스트를 생성하지 않는다.
🚨 tuple, range, 문자열은 del로 슬라이스를 삭제할 수 없다.