시퀀스 및 인덱스 활용
리스트, 튜플, range, 문자열처럼 값이 연속적으로 이어진 자료형을 시퀀스 자료형(sequence types)라고 부름.
> list, tuple, range, str, bytes, bytearray
시퀀스 객체에 들어있는 각 값을 요소(element)라고 부름.
>>> 43 in (38, 76, 43, 62, 19)
True
>>> 1 in range(10)
True
>>> 'P' in 'Hello, Python'
True
>>> a = [0, 10, 20, 30]
>>> b = [9, 8, 7, 6]
>>> a + b
[0, 10, 20, 30, 9, 8, 7, 6]
range는 +로 객체를 연결할 수 없으며 리스트나 튜플로 만들어서 연결해야 한다.
>>> range(0, 10) + range(10, 20)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
range(0, 10) + range(10, 20)
TypeError: unsupported operand type(s) for +: 'range' and 'range'
>>> list(range(0, 10)) + list(range(10, 20))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> tuple(range(0, 10)) + tuple(range(10, 20))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
문자열과 숫자는 연결할 수 없다.
연결하고 싶다면 str()을 사용한다.
>>> 'Hello, ' + 10
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
'Hello, ' + 10
TypeError: Can't convert 'int' object to str implicitly
>>> 'Hello, ' + str(10) # str을 사용하여 정수를 문자열로 변환
'Hello, 10'
>>> 'Hello, ' + str(1.5) # str을 사용하여 실수를 문자열로 변환
'Hello, 1.5'
>>> [0, 10, 20, 30] * 3
[0, 10, 20, 30, 0, 10, 20, 30, 0, 10, 20, 30]
>>> 'Hello, ' * 3
'Hello, Hello, Hello, '
>>> list(range(0, 5, 2)) * 3
[0, 2, 4, 0, 2, 4, 0, 2, 4]
>>> tuple(range(0, 5, 2)) * 3
(0, 2, 4, 0, 2, 4, 0, 2, 4)
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> len(a)
10
>>> b = (38, 76, 43, 62, 19)
>>> len(b)
5
>>> len(range(0, 10, 2))
5
>>> hello = 'Hello, world!'
>>> len(hello)
13
>>> hello = '안녕하세요'
>>> len(hello)
5
UTF-8 문자열의 바이트 수 구하기
한글, 한자, 일본어 등은 UTF-8인코딩으로 저장하는데 문자열이 차지하는 실제 바이트 수를 구하는 방법
>>> hello = '안녕하세요'
>>> len(hello.encode('utf-8'))
15
> utf-8에서 한글 글자 하나는 3바이트이다.
>>> a = [38, 21, 53, 62, 19]
>>> a[0] # 리스트의 첫 번째(인덱스 0) 요소 출력
38
>>> b = (38, 21, 53, 62, 19)
>>> b[0] # 튜플의 첫 번째(인덱스 0) 요소 출력
38
>>> r = range(0, 10, 2)
>>> r[2] # range의 세 번째(인덱스 2) 요소 출력
4
>>> hello = 'Hello, world!'
>>> hello[7] # 문자열의 여덟 번째(인덱스 7) 요소 출력
'w'
>>> a = [38, 21, 53, 62, 19]
>>> a[-1] # 리스트의 뒤에서 첫 번째(인덱스 -1) 요소 출력
19
>>> a[-5] # 리스트의 뒤에서 다섯 번째(인덱스 -5) 요소 출력
38
- __getitem__ 메서드
시퀀스 객체에서 를 사용하면 실제로는 getitem 메서드를 호출하여 요소를 가져옵니다. 따라서 다음과 같이 getitem 메서드를 직접 호출하여 요소를 가져올 수도 있습니다.
>>> a = [38, 21, 53, 62, 19]
>>> a.__getitem__(1)
21
>>> a[1]
21
>>> a = [0, 0, 0, 0, 0] # 0이 5개 들어있는 리스트
>>> a[0] = 38
>>> a[1] = 21
>>> a[2] = 53
>>> a[3] = 62
>>> a[4] = 19
>>> a
[38, 21, 53, 62, 19]
>>> a[0]
38
>>> a[4]
19
>>> b = (0, 0, 0, 0, 0)
>>> b[0] = 38
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
b[0] = 38
TypeError: 'tuple' object does not support item assignment
>>> r = range(0, 10, 2)
>>> r[0] = 3
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
r[0] = 3
TypeError: 'range' object does not support item assignment
>>> hello = 'Hello, world!'
>>> hello[0] = 'A'
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
hello[0] = 'A'
TypeError: 'str' object does not support item assignment
11.4 슬라이스
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[1:1] # 인덱스 1부터 0까지 잘라서 새 리스트를 만듦
[]
>>> a[1:2] # 인덱스 1부터 1까지 잘라서 새 리스트를 만듦
[10]
시퀀스객체[시작인덱스:끝인덱스:인덱스증가폭]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:3] # 인덱스 2부터 3씩 증가시키면서 인덱스 7까지 가져옴
[20, 50]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:7] # 리스트 처음부터 인덱스 6까지 가져옴
[0, 10, 20, 30, 40, 50, 60]
>>> a[:] # 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:7:2] # 리스트의 처음부터 인덱스를 2씩 증가시키면서 인덱스 6까지 가져옴
[0, 20, 40, 60]
>>> a[7::2] # 인덱스 7부터 2씩 증가시키면서 리스트의 마지막 요소까지 가져옴
[70, 90]
>>> a[::2] # 리스트 전체에서 인덱스 0부터 2씩 증가시키면서 요소를 가져옴
[0, 20, 40, 60, 80]
>>> a[::] # 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[5:1:-1]
[50, 40, 30, 20]
>>> a[::-1]
[90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[0:len(a)] # 시작 인덱스에 0, 끝 인덱스에 len(a) 지정하여 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[:len(a)] # 시작 인덱스 생략, 끝 인덱스에 len(a) 지정하여 리스트 전체를 가져옴
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> b = (0, 10, 20, 30, 40, 50, 60, 70, 80, 90)
>>> b[4:7] # 인덱스 4부터 6까지 요소 3개를 가져옴
(40, 50, 60)
>>> b[4:] # 인덱스 4부터 마지막 요소까지 가져옴
(40, 50, 60, 70, 80, 90)
>>> b[:7:2] # 튜플의 처음부터 인덱스를 2씩 증가시키면서 인덱스 6까지 가져옴
(0, 20, 40, 60)
>>> r = range(10)
>>> r
range(0, 10)
>>> r[4:7] # 인덱스 4부터 6까지 숫자 3개를 생성하는 range 객체를 만듦
range(4, 7)
>>> r[4:] # 인덱스 4부터 9까지 숫자 6개를 생성하는 range 객체를 만듦
range(4, 10)
>>> r[:7:2] # 인덱스 0부터 2씩 증가시키면서 인덱스 6까지 숫자 4개를 생성하는 range 객체를 만듦
range(0, 7, 2)
>>> list(r[:7:2])
[0, 2, 4, 6]
슬라이스객체 = slice(끝인덱스)
슬라이스객체 = slice(시작인덱스, 끝인덱스)
슬라이스객체 = slice(시작인덱스, 끝인덱스, 인덱스증가폭)
시퀀스객체[슬라이스객체]
시퀀스객체.getitem(슬라이스객체)
>>> range(10)[slice(4, 7, 2)]
range(4, 7, 2)
>>> range(10).__getitem__(slice(4, 7, 2))
range(4, 7, 2)
slice객체를 하나만 만든 뒤 여러 시퀀스 객체에 사용 가능.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> s = slice(4, 7) # 인덱스 4부터 6까지 자르는 slice 객체 생성
>>> a[s]
[40, 50, 60]
>>> r = range(10)
>>> r[s]
range(4, 7)
>>> hello = 'Hello, world!'
>>> hello[s]
'o, '
- 슬라이스에 요소 할당하기
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:5] = ['a', 'b', 'c'] # 인덱스 2부터 4까지 값 할당
>>> a
[0, 10, 'a', 'b', 'c', 50, 60, 70, 80, 90]
꼭 개수를 맞추지 않아도 된다.
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:5] = ['a'] # 인덱스 2부터 4까지에 값 1개를 할당하여 요소의 개수가 줄어듦
>>> a
[0, 10, 'a', 50, 60, 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:5] = ['a', 'b', 'c', 'd', 'e'] # 인덱스 2부터 4까지 값 5개를 할당하여 요소의 개수가 늘어남
>>> a
[0, 10, 'a', 'b', 'c', 'd', 'e', 50, 60, 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:2] = ['a', 'b', 'c'] # 인덱스 2부터 2씩 증가시키면서 인덱스 7까지 값 할당
>>> a
[0, 10, 'a', 30, 'b', 50, 'c', 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> a[2:8:2] = ['a', 'b']
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
a[2:8:2] = ['a', 'b']
ValueError: attempt to assign sequence of size 2 to extended slice of size 3
>>> b = (0, 10, 20, 30, 40, 50, 60, 70, 80, 90)
>>> b[2:5] = ('a', 'b', 'c')
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
b[2:5] = ('a', 'b', 'c')
TypeError: 'tuple' object does not support item assignment
>>> r = range(10)
>>> r[2:5] = range(0, 3)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
r[2:5] = range(0, 3)
TypeError: 'range' object does not support item assignment
>>> hello = 'Hello, world!'
>>> hello[7:13] = 'Python'
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
hello[7:13] = 'Python'
TypeError: 'str' object does not support item assignment
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> del a[2:5] # 인덱스 2부터 4까지 요소를 삭제
>>> a
[0, 10, 50, 60, 70, 80, 90]
>>> a = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> del a[2:8:2] # 인덱스 2부터 2씩 증가시키면서 인덱스 6까지 삭제
>>> a
[0, 10, 30, 50, 70, 80, 90]
튜플, 문자열, range는 del로 슬라이스 삭제 불가능