여러 값을 다루는 순간, 프로그램이 진짜로 재미있어진다
앞에서 우리는 숫자 하나, 문자열 하나, 불리언 하나처럼 값 하나를 다뤘습니다. 그런데 실제 프로그램은 대부분 값 하나로는 부족합니다. 장바구니에는 상품이 여러 개 들어가고, 학생 정보에는 이름과 점수가 함께 들어가며, 로그인한 사용자 목록에는 중복 없이 여러 이름이 저장되어야 합니다.
이럴 때 필요한 것이 바로 컬렉션 자료형입니다. 컬렉션은 여러 데이터를 한 번에 담는 그릇이라고 생각하면 쉽습니다. 파이썬에서 가장 자주 쓰는 컬렉션은 네 가지입니다.1
리스트(list): 순서가 있고, 수정할 수 있는 자료형
튜플(tuple): 순서가 있지만, 수정할 수 없는 자료형
딕셔너리(dictionary): 이름표 같은 키로 값을 찾는 자료형
집합(set): 중복 없이 값만 모아 두는 자료형
이 네 가지를 잘 구분해서 쓰면, 코드가 훨씬 읽기 쉬워지고 문제도 더 똑똑하게 풀 수 있습니다.2
먼저 감으로 잡아보는 네 가지 그릇
비유로 먼저 이해해 봅시다.
리스트는 순서대로 적는 메모장입니다. 첫 번째, 두 번째, 세 번째가 중요하고, 중간에 내용을 바꾸거나 새 항목을 추가할 수 있습니다.
튜플은 변경하면 안 되는 기록지입니다. 좌표, 생년월일, RGB 색상처럼 한 번 정하면 바꾸지 않는 데이터를 담을 때 잘 어울립니다.
딕셔너리는 이름표가 붙은 서랍장입니다. "name", "age", "score" 같은 키를 붙여 두고 필요한 값을 바로 꺼냅니다.
집합은 중복을 허용하지 않는 주머니입니다. 이미 들어 있는 값은 또 넣어도 하나만 남습니다. 그래서 중복 제거에 아주 유용합니다.
이제 하나씩 천천히 살펴보겠습니다.
리스트: 가장 먼저 친해져야 할 만능 상자
리스트는 가장 많이 쓰는 컬렉션입니다. 대괄호 []로 만들고, 여러 값을 순서대로 저장합니다.
fruits = ["apple", "banana", "cherry"]
print(fruits)리스트는 순서가 있다는 점이 중요합니다. 그래서 인덱스(index)로 값을 꺼낼 수 있습니다. 인덱스는 위치 번호인데, 파이썬에서는 0부터 시작합니다.
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # apple
print(fruits[1]) # banana
print(fruits[-1]) # cherry-1은 뒤에서 첫 번째를 뜻합니다. 그래서 마지막 값을 꺼낼 때 자주 씁니다.
리스트는 수정이 가능합니다. 이것을 가변(mutable) 자료형이라고 합니다.1
fruits = ["apple", "banana", "cherry"]
fruits[1] = "mango"
print(fruits)리스트에 자주 쓰는 기능도 알아둡시다.
numbers = [3, 1, 4]
numbers.append(5) # 맨 뒤에 추가
numbers.insert(1, 2) # 원하는 위치에 추가
numbers.remove(4) # 값으로 삭제
last = numbers.pop() # 마지막 값을 꺼내면서 삭제
print(numbers)
print(last)리스트 메서드인 append(), insert(), remove(), pop(), sort() 같은 기능은 실제로 매우 자주 쓰입니다.3
리스트 자르기: 필요한 부분만 쏙 꺼내기
리스트는 한 칸만 꺼내는 것뿐 아니라, 여러 칸을 잘라서 가져올 수도 있습니다. 이것을 슬라이싱(slicing)이라고 합니다. 어렵게 들리지만 사용법은 간단합니다.
nums = [10, 20, 30, 40, 50]
print(nums[1:4]) # [20, 30, 40]
print(nums[:3]) # [10, 20, 30]
print(nums[2:]) # [30, 40, 50]
print(nums[::-1]) # [50, 40, 30, 20, 10][시작:끝]에서 끝 위치는 포함되지 않는다는 점을 꼭 기억하세요. 초보자가 가장 자주 헷갈리는 부분입니다.
리스트는 이런 상황에서 잘 맞는다
리스트는 다음처럼 순서가 중요하고, 나중에 바뀔 수 있는 데이터에 잘 어울립니다.
할 일 목록
장바구니 상품 목록
시험 점수 목록
최근 검색어 목록
예를 들어 장바구니는 상품이 계속 추가되거나 삭제될 수 있으니 리스트가 자연스럽습니다.
cart = ["notebook", "pen"]
cart.append("eraser")
cart.remove("pen")
print(cart)튜플: 바뀌지 않아야 더 안전한 데이터
튜플은 리스트와 비슷하지만, 한 가지 큰 차이가 있습니다. 만든 뒤에 내용을 바꿀 수 없다는 것입니다. 튜플은 소괄호 ()로 만듭니다.
point = (3, 7)
print(point)튜플도 순서가 있기 때문에 인덱스로 접근할 수 있습니다.
point = (3, 7)
print(point[0])
print(point[1])하지만 수정은 되지 않습니다.
point = (3, 7)
# point[0] = 10 # 오류 발생이런 자료형을 불변(immutable) 자료형이라고 합니다.1
튜플은 왜 필요할까요? 바꿀 수 없다는 점이 오히려 장점이 됩니다. 실수로 값이 바뀌면 안 되는 데이터를 안전하게 보관할 수 있기 때문입니다.
예를 들어 다음과 같은 데이터에 잘 어울립니다.
좌표
(x, y)날짜
(year, month, day)RGB 색상
(255, 128, 0)한 번 정하면 쉽게 바뀌지 않는 정보 묶음
튜플 언패킹: 한 번에 나눠 담기
튜플의 아주 편리한 기능 중 하나는 언패킹(unpacking)입니다. 튜플 안의 값을 여러 변수에 한 번에 꺼내 담는 방법입니다.
person = ("민지", 20, "서울")
name, age, city = person
print(name)
print(age)
print(city)이 기능은 읽기 쉬운 코드를 만드는 데 큰 도움이 됩니다.
원소가 하나인 튜플은 쉼표가 필요하다
이건 작은 함정입니다.
a = (10)
print(type(a))
b = (10,)
print(type(b))(10)은 그냥 정수이고, (10,)처럼 쉼표를 붙여야 튜플입니다. 처음 배우는 사람이라면 꼭 한 번쯤 만나는 함정입니다.
딕셔너리: 이름으로 찾는 똑똑한 보관함
딕셔너리는 키(key)와 값(value)의 쌍으로 데이터를 저장합니다. 중괄호 {}를 사용하고, 키: 값 형태로 작성합니다.
student = {
"name": "지우",
"age": 18,
"score": 95
}
print(student)리스트는 위치로 찾고, 딕셔너리는 이름표 같은 키로 찾습니다.
student = {
"name": "지우",
"age": 18,
"score": 95
}
print(student["name"])
print(student["score"])딕셔너리의 키는 고유해야 합니다. 같은 키를 두 번 쓰면 뒤의 값이 앞의 값을 덮어씁니다.2
student = {
"name": "지우",
"score": 90
}
student["score"] = 95
print(student)값을 추가하는 것도 쉽습니다.
student["grade"] = 2
print(student)get()으로 안전하게 꺼내기
딕셔너리에서 존재하지 않는 키를 바로 꺼내면 오류가 날 수 있습니다.
student = {"name": "지우"}
# print(student["phone"]) # 오류 발생이럴 때는 get()을 쓰면 편합니다.
student = {"name": "지우"}
print(student.get("phone"))
print(student.get("phone", "없음"))키가 없으면 None 또는 내가 정한 기본값을 돌려줍니다. 초보자에게 아주 든든한 기능입니다.
딕셔너리 반복하기
딕셔너리는 보통 세 방식으로 많이 꺼내 봅니다.
keys(): 키들 보기values(): 값들 보기items(): 키와 값을 함께 보기
student = {
"name": "지우",
"age": 18,
"score": 95
}
for key, value in student.items():
print(key, value)현재 파이썬에서는 딕셔너리가 입력한 순서를 유지합니다.3 그래서 보통 넣은 순서대로 키와 값이 보입니다. 다만 딕셔너리의 핵심은 어디까지나 키로 값을 빠르게 찾는 자료형이라는 점입니다.
딕셔너리는 이런 상황에서 잘 맞는다
딕셔너리는 어떤 값에 이름을 붙여 관리하고 싶을 때 정말 편합니다.
학생 정보
게임 캐릭터 상태
설정값 모음
상품 코드와 재고 수량
예를 들어 학생 여러 명을 저장할 때는 리스트와 딕셔너리를 함께 쓰는 경우가 많습니다.
students = [
{"name": "지우", "score": 95},
{"name": "민호", "score": 88},
{"name": "서연", "score": 92}
]
print(students[0]["name"])이렇게 하면 여러 명의 데이터를 리스트에 넣고, 한 사람의 세부 정보는 딕셔너리로 다룰 수 있습니다.
집합: 중복 제거의 달인
집합은 중복되지 않는 값들만 저장하는 자료형입니다. 역시 중괄호 {}를 쓰지만, 딕셔너리처럼 키: 값이 아니라 값만 나열합니다.
nums = {1, 2, 3, 3, 3, 4}
print(nums)출력 결과에는 3이 하나만 남습니다. 집합은 자동으로 중복을 없애기 때문입니다.2
집합은 순서가 없고 인덱스로 접근할 수 없습니다. 그래서 nums[0] 같은 코드는 사용할 수 없습니다.
fruits = {"apple", "banana", "cherry"}
fruits.add("orange")
fruits.discard("banana")
print(fruits)여기서 discard()는 값이 없어도 조용히 넘어가고, remove()는 값이 없으면 오류가 납니다. 처음에는 discard()가 더 편하게 느껴질 수 있습니다.
집합의 진짜 강점: 빠른 포함 검사와 집합 연산
집합은 어떤 값이 들어 있는지 검사할 때 매우 유용합니다. 또 수학 시간에 배운 합집합, 교집합, 차집합도 쉽게 구할 수 있습니다.2
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # 합집합
print(a & b) # 교집합
print(a - b) # 차집합
print(a ^ b) # 대칭차집합예를 들어 두 반 모두 신청한 학생을 찾고 싶다면 교집합을 쓰면 됩니다.
python_class = {"지우", "민호", "서연"}
math_class = {"민호", "서연", "도윤"}
both = python_class & math_class
print(both)빈 집합은 set()으로 만든다
이것도 아주 자주 하는 실수입니다.
a = {}
print(type(a))이 코드는 빈 집합이 아니라 빈 딕셔너리를 만듭니다. 빈 집합을 만들려면 이렇게 해야 합니다.
a = set()
print(type(a))네 자료형을 한눈에 비교하기
아래 표는 꼭 머릿속에 넣어 두면 좋습니다.
| 자료형 | 순서 | 수정 가능 | 중복 허용 | 접근 방식 | 잘 어울리는 상황 |
|---|---|---|---|---|---|
| 리스트 | O | O | O | 인덱스 | 할 일 목록, 장바구니 |
| 튜플 | O | X | O | 인덱스 | 좌표, 날짜, 고정 정보 |
| 딕셔너리 | 입력 순서 유지, 키 중심 | O | 키는 X | 키 | 학생 정보, 설정값 |
| 집합 | X | O | X | 포함 여부 검사 | 중복 제거, 공통 항목 찾기 |
정말 짧게 기억하면 이렇습니다.
리스트는 바뀌는 순서 있는 모음, 튜플은 안 바뀌는 순서 있는 모음, 딕셔너리는 이름표로 찾는 모음, 집합은 중복 없는 모음입니다.
어떤 자료형을 골라야 할까
자료형 선택은 결국 질문 하나로 정리됩니다. "내가 이 데이터를 어떻게 꺼내고, 바꾸고, 비교할 것인가?"
순서가 중요하고 수정도 자주 한다면 리스트가 잘 맞습니다. 예를 들어 오늘 해야 할 일 목록은 계속 추가되고 순서도 있으니 리스트가 자연스럽습니다.
값이 정해진 뒤 바뀌지 않아야 한다면 튜플을 고려하면 좋습니다. 좌표나 시험장의 자리 번호처럼 의미가 고정된 데이터가 여기에 가깝습니다.
특정 이름으로 바로 값을 찾고 싶다면 딕셔너리를 쓰면 됩니다. "name", "price", "email"처럼 키가 분명한 데이터는 딕셔너리가 아주 편합니다.
중복을 없애거나 공통 원소를 찾는 것이 핵심이라면 집합이 딱 맞습니다. 참석자 명단에서 중복 이름을 제거하거나, 두 목록의 공통 항목을 찾을 때 특히 빛납니다.
실전 예제로 한 번에 정리하기
이제 네 자료형을 한 장면에서 같이 써 보겠습니다. 동아리 출석을 관리한다고 해 봅시다.
# 오늘 출석 체크를 순서대로 기록
attendance_list = ["지우", "민호", "지우", "서연", "민호"]
# 중복 제거
attendance_set = set(attendance_list)
# 고정된 동아리 정보
club_info = ("파이썬 동아리", "월요일", "3층")
# 학생별 점수
scores = {
"지우": 95,
"민호": 88,
"서연": 92
}
print("출석 기록:", attendance_list)
print("중복 제거 후:", attendance_set)
print("동아리 정보:", club_info)
print("지우 점수:", scores["지우"])이 예제에서 리스트는 기록 순서를 살리고, 집합은 중복 제거를 하고, 튜플은 바뀌지 않을 정보를 담고, 딕셔너리는 이름으로 점수 찾기를 담당합니다. 이렇게 자료형을 역할에 맞게 고르면 코드가 한결 또렷해집니다.
초보자가 자주 하는 실수
여기서는 정말 많이 나오는 실수만 모아 보겠습니다.
리스트와 튜플을 헷갈리기
리스트는 바꿀 수 있고, 튜플은 바꿀 수 없습니다. 수정할 일이 있다면 리스트를 써야 합니다.
colors = ("red", "green", "blue")
# colors.append("yellow") # 오류집합에 순서를 기대하기
집합은 순서가 없습니다. 그래서 첫 번째 값, 두 번째 값을 꺼내는 식으로 다루면 안 됩니다.
딕셔너리의 없는 키를 바로 꺼내기
없는 키를 student["phone"]처럼 바로 꺼내면 오류가 날 수 있습니다. 안전하게 get()을 쓰는 습관을 들이면 좋습니다.
{}를 빈 집합으로 착각하기
{}는 빈 딕셔너리입니다. 빈 집합은 set()입니다.
이번 장의 핵심 정리
이번 장에서 꼭 기억할 것은 다음 네 문장입니다.
리스트는 순서가 있고 수정 가능한 모음이다.
튜플은 순서가 있지만 수정 불가능한 모음이다.
딕셔너리는 키로 값을 찾는 자료형이다.
집합은 중복 없는 값들의 모음이다.
프로그래밍 실력은 문법을 많이 외우는 것보다, 어떤 데이터를 어떤 그릇에 담아야 하는지 판단하는 힘에서 크게 자랍니다. 같은 데이터라도 리스트에 담을지, 딕셔너리에 담을지, 집합에 담을지에 따라 코드의 모습이 완전히 달라집니다.
지금은 네 가지를 완벽하게 외우려고 애쓰기보다, 작은 예제를 자꾸 만들어 보세요. 이름 목록은 리스트로, 좌표는 튜플로, 학생 정보는 딕셔너리로, 중복 제거는 집합으로 바꿔 보는 연습을 하다 보면 어느 순간 손이 먼저 반응하게 됩니다.
다음 장에서는 이 컬렉션들 안에 들어 있는 문자열을 더 잘 다루는 방법을 배워 보겠습니다. 데이터를 잘 담는 법을 익혔다면, 이제는 그 데이터를 깔끔하게 가공할 차례입니다.
참고
1Python Data Structures: Lists, Dictionaries, Sets, Tuples
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.