이번 장에서는 여러 개의 데이터를 하나로 묶어서 처리하는 리스트와 튜플을 배워보자.
지금까지는 주로 숫자와 문자열을 변수에 저장하였다.
하지만 어떤 경우에는 여러 개의 데이터를 하나로 묶어서 저장하는 것이 필요하다.
파이썬에서는 "리스트 list" 와 딕셔너리"dictionary" 를 이용하여 여러 개의 데이터를
한꺼번에 저장하고 처리할 수 있다.
height = 174.2
학생 한 명의 키를 저장한다면 위와 같이 변수에 실수 데이터를 저장하면 된다.
하지만 학생 5명의 키를 저장하려면 어떻게 해야 할까?
5명이 아니라 100명, 1000명이라면 어떻게 해야 할까?
데이터를 하나씩 변수에 저장하려면 번거롭기도 하고 관리하기도 어렵다.
이와 같은 경우 "리스트 list" 를 이용하여 처리하면 편하게 처리할 수 있다.
파이썬에서는 리스트를 대괄호를 이용하여 만든다.
예를 들어, 학생 5명의 키를 리스트에 저장하려면 다음과 같이 하면 된다.
heights = [174.2, 173.5, 166.7, 178.1, 164.3]
위와 같이 코드를 작성하면 heights 라는 이름의 리스트가 만들어진다.
그리고 이 리스트에 여러 개의 변수를 담을 수 있다.
리스트를 사용하면 여러 개의 변수를 하나의 변수로 표현할 수 있고 이 실수값들은
인덱스를 이용해서 접근할 수 있다.
174.2 | 173.5 | 166.7 | 178.1 | 164.3 |
다음과 같이 heights 리스트 변수에는 실수 데이터가 담겨있는데 인덱스는 0부터 시작한다.
즉, 리스트의 0번째 인덱스에는 첫번째 실수 데이터인 174.2 가 담겨있고
1번째 인덱스에는 두번째 실수 데이터인 173.5 가 담겨있다.
해당 데이터에 각각 접근하고 싶다면 heights[0] 과 같이 인덱스를 지정해주면 된다.
초기에 멤버가 없는 빈 리스트도 생성할 수 있다.
그럴 땐 빈 괄호를 이용하면 된다.
num_list = []
리스트에 값을 추가하는 것도 가능하다. 그럴 때는 append 메소드를 사용한다.
num_list = []
num_list.append(30) # 리스트에 숫자 30 추가
연속된 정수 리스트는 range() 함수를 이용해서 만들 수 있다.
range() 함수는 (start, end, step) 을 인자로 가지는데, start 와 step 은 생략 가능하고, end 값은 꼭 필요하다.
start 의 디폴트 값은 0 이고, step 의 디폴트 값은 1이다.
range() 함수는 for 문과 같은 반복문에 아주 빈번하게 사용되니 꼭 알아두어야 한다.
list(range(5)) # [0, 1, 2, 3, 4]
list(range(0, 5)) # [0, 1, 2, 3, 4]
list(range(0, 5, 1)) # [0, 1, 2, 3, 4]
list(range(0, 5, 2)) # [0, 2, 4]
list(range(2, 5)) # [2, 3, 4]
list() 는 괄호 안의 값을 리스트 형식으로 반환해준다.
range() 함수를 이용해서 생성된 정수들을 리스트 형식으로 출력해보면 위와 같다.
파이썬에서는 리스트에 대해서 다양한 연산이 가능하다.
덧셈 연산으로 두 개의 리스트를 합칠 수도 있다.
num1 = [1, 2, 3]
num2 = [4, 5, 6]
print(num1 + num2)
위의 코드에서는 num1 리스트에 1,2,3 을 넣어주고,
num2 리스트에 4,5,6 을 넣어주었다.
그리고 num1 리스트와 num2 리스트를 더해서 출력해보았다.
어떻게 출력될까?
위와 같이 리스트가 합쳐진다는 것을 볼 수 있다.
그렇다면 이번에는 사용자의 입력을 받아 맛있는 과일의 리스트를 만들어보자.
빈 리스트를 생성한 다음 사용자로부터 제일 좋아하는 3개의 과일을 입력받아서 리스트에 저장한다.
그리고 과일의 이름을 하나 더 입력받고 그 과일이 리스트에 포함되어 있으면
'좋아하는 과일이 맞다' 고 출력하고, 그렇지 않으면 ' 좋아하는 과일이 아니다' 라고 출력해보자.
밑의 코드를 보기 전에 직접 코드를 작성해보자.
fruits = []
for i in range(3):
name = input('좋아하는 과일의 이름을 입력하시오: ')
fruits.append(name)
name = input('과일의 이름을 입력하세요: ')
if name in fruits:
print('이 과일은 당신이 좋아하는 과일입니다.')
else:
print('이 과일은 당신이 좋아하는 과일이 아닙니다.')
해답 코드는 위와 같다. fruits = [] 로 빈 리스트를 생성한 후 반복문을 이용하여 과일의 이름을
3번 입력받는다. 입력받은 과일의 이름을 append() 메소드를 이용하여 리스트에 추가하고 있다.
그리고 과일의 이름을 하나 더 입력 받은 후, 조건문을 사용하여 fruits 리스트에 과일의 이름이 있으면
좋아하는 과일이라고 출력하고, 아니면 아니라고 출력하는 것이다.
리스트에 해당 데이터가 있는 확인하는 키워드는 "in" 이다.
반복문에서도 in 키워드가 사용되었는데 이는 0, 1, 2 의 정수 데이터를 하나씩 i 변수에 가져온다는 의미이다.
반복문 안에서 i 변수의 값을 직접 사용하지는 않았지만, for loop 를 사용할 때 위와 같이
range() 함수를 이용해서 빈번하게 사용한다.
반복문에 대해서 잘 이해가 가지 않는다면 다음 글을 참고하자.
위 코드를 실행하면 다음과 같다.
리스트에서는 인덱스를 사용해 요소에 접근할 수 있다고 위에 잠깐 언급했었다.
그렇다면 인덱스를 자유자재로 사용해 원하는 모양으로 자르는 "슬라이싱 slicing" 에 대해서 알아보자.
우선 리스트를 다음과 같이 저장해보자.
letters = ['A', 'B', 'C', 'D', 'E', 'F']
이 리스트에서 데이터를 추출하기 위해 인덱스를 사용해보자.
letters[0] 은 첫 번째 요소를 가져온다. 즉, 'A' 라는 데이터를 가져올 것이다.
두 번째 요소는 letters[1], 세 번째 요소는 letters[2] 와 같이 사용하면 될 것이다.
파이썬에서 특이한 점은 인덱스를 음수로 줄 수 있다는 점이다.
리스트 맨 끝에 있는 데이터를 가져오고자 할 때는 letters[-1] 과 같이 인덱스를 -1 로 준다.
print(letters[-1])
위 코드의 실행결과는 어떻게 될까?
리스트의 가장 마지막 데이터인 'F' 가 출력된다.
그리고 파이썬에는 다양한 함수를 리스트에 적용해 편리하게 사용할 수 있다.
원소의 개수를 알 수 있는 len(), 리스트의 원소들 중에서 최솟값을 찾는 min(),
최댓값을 찾는 max() 함수 등이 해당한다.
numbers = [1, 2, 3, 4, 5, 6]
print('리스트의 길이:', len(numbers)) # 리스트의 길이
print('리스트 원소 중 최솟값:', min(numbers)) # 리스트에서 최솟값
print('리스트 원소 중 최댓값:', max(numbers)) # 리스트에서 최댓값
위 코드를 실행하면 어떻게 출력될까?
출력 결과는 위와 같다.
그렇다면 이번에는 리스트에서 여러 요소를 선택해서 새로운 리스트를 만들어보자.
위에서 언급했던 "슬라이싱 slicing" 이라는 기능을 사용하면 된다.
리스트를 슬라이싱하려면 다음과 같이 콜론(:)을 사용하여 범위를 지정하면 된다.
letters = ['A', 'B', 'C', 'D', 'E', 'F']
print(letters[2:5])
# ['C', 'D', 'E']
슬라이싱을 할 때 letters[2:5] 와 같이 적으면 2부터 시작하여서 항목들을 추출하다가
5가 나오기 전에 중지한다. range() 함수와 비슷하다.
따라서 추출되는 요소의 인덱스는 2,3,4 가 되고 인덱스 5는 포함되지 않는다는 점에 주의하자.
리스트를 슬라이싱하면 원래 리스트가 바뀌는 것이 아니라 새로운 리스트가 생성되어서 반환된다.
원래 리스트의 부분 복사본이라고 생각하면 되겠다.
슬라이싱에서 첫 번째 인덱스를 생략하면 무조건 리스트의 처음부터라고 가정하고,
두 번째 인덱스가 생략되면 리스트의 끝까지라고 가정한다.
letters = ['A', 'B', 'C', 'D', 'E', 'F']
print(letters[:3]) # ['A', 'B', 'C']
print(letters[3:]) # ['D', 'E', 'F']
또 step 값을 세 번째 원소로 넣어 step 만큼 건너뛰면서 원소를 추출할 수도 있다.
다음과 같이 letters[::2] 를 호출하면 'A' 다음의 'B' 는 건너뛰어 'C' 가 출력되고,
또 'D' 는 건너뛰어 'E' 를 출력한다.
letters = ['A', 'B', 'C', 'D', 'E', 'F']
print(letters[::2]) # ['A', 'C', 'E']
만일 step 을 -1 과 같이 음수로 주면 뒤에서부터 앞으로 읽어오면서 원소를 생성한다.
letters = ['A', 'B', 'C', 'D', 'E', 'F']
print(letters[::-1]) # ['F', 'E', 'D', 'C', 'B', 'A']
리스트에는 다양한 메소드들이 존재한다.
메소드 | 하는 일 |
index(x) | 원소 x를 이용하여 위치를 찾는 기능을 한다. |
append(x) | 원소 x를 리스트의 끝에 추가한다. |
count(x) | 리스트 내에서 x 원소의 개수를 반환한다. |
extend([x1, x2]) | [x1, x2] 리스트를 기존 리스트에 삽입한다. |
insert(index, x) | 원하는 index에 x를 추가한다. |
remove(x) | x 원소를 리스트에서 삭제한다. |
pop(index) | index 위치의 원소를 삭제한 후 반환한다. |
sort() | 값을 오름차순 순서대로 정렬, 키워드 인자 reverse=True 이면 내림차순 |
reverse() | 리스트를 원래 원소들의 역순으로 만들어준다. |
그렇다면 이번에는 "튜플 tuple" 이라는 자료형에 대해 살펴보자.
리스트는 내용을 자유롭게 변경할 수 있는 "가변속성 mutable" 자료형인 것에 비해
튜플은 대표적인 "불변속성 immutable" 자료형이다.
그렇다면 왜 자유롭게 내용을 변경할 수 없는 튜플을 사용하는 것일까?
튜플은 한 번 그 내용이 정해지면 변경이 불가능하므로 구조가 단순하고 리스트에 비해 접근 속도가 빠르다.
따라서 두 자료형은 목적에 따라서 적합한 경우에 선택하여 사용한다.
튜플 생성은 소괄호 () 안에 요소들을 넣으면 된다.
예를 들어 색상 데이터를 저장하는 튜플을 만들어보자.
color = ('red', 'green', 'blue')
print(color) # ('red', 'green', 'blue')
튜플은 변경될 수 없는 객체이므로 리스트에서 하던 것과 같이 인덱스를 지정하여
해당 인덱스의 값을 변경하려고 하면 에러가 출력된다.
다만 튜플도 시퀀스의 일종이기 때문에 인덱싱과 슬라이싱은 동일하게 동작한다.
앞 장에서도 언급했듯이 함수에서 여러 개의 값을 return 받을 때 튜플 자료형으로 반환받을 수도 있다.
이번 장에서는 파이썬의 대표 자료형이라고 할 수 있는 리스트와 튜플에 대해서 알아보았다.
C 나 Java 와 같은 언어에서 흔히 접하던 int, char 같은 자료형이 아닌
사용자가 쓰기에 편리한 자료형인만큼, 많이 숙지하고 익숙해지면 강력하게 사용할 수 있을 것이라 느꼈다.
어떨 때 어떤 자료형을 사용해야 하는 지 익히고, 자유자재로 쓸 수 있는 프로그래머가 되어보자.
출처 : 따라하며 배우는 파이썬과 데이터 과학 - 천인국, 박동규, 강영민