본문 바로가기
자기 개발/Python

파이썬(Python) 공부 7편 — 리스트·튜플·딕셔너리·집합 완전 정복 | 메서드·컴프리헨션·비교까지

by conrad 2026. 3. 31.
07 / 15 Python 공부 시리즈 — 컬렉션 자료형
← 6편: 함수(Function) 완전 정복 보러 가기
Python 공부 시리즈 · 7편 | list · tuple · dict · set · comprehension

파이썬(Python) 공부 7편
리스트·튜플·딕셔너리·집합 완전 정복

파이썬에는 여러 데이터를 묶어서 관리하는 네 가지 컬렉션 자료형이 있습니다. 리스트·튜플·딕셔너리·집합은 각각 특성이 다르기 때문에 상황에 맞게 골라 쓰는 것이 중요합니다. 메서드 총정리부터 컴프리헨션까지 한 번에 정리합니다.

list — 순서O 중복O 변경O tuple — 순서O 불변 dict — 키-값 쌍 set — 중복X 집합연산 컴프리헨션

📊 4가지 컬렉션 — 한눈에 비교

list 리스트 [ ]

순서 O / 중복 O / 변경 O
가장 자주 쓰이는 자료형.
인덱스로 접근, 추가·삭제·수정 모두 가능.
예: [1, 2, 3, "python"]

tuple 튜플 ( )

순서 O / 중복 O / 변경 X (불변)
한 번 만들면 수정 불가. 리스트보다 빠름.
좌표, 고정 데이터, 함수 반환값에 사용.
예: (10, 20, "Seoul")

dict 딕셔너리 { }

키-값(key-value) 쌍 / 키는 고유
키로 빠르게 값 조회. Python 3.7+부터 삽입 순서 유지.
JSON 데이터 처리에 필수.
예: {"name": "Alice", "age": 25}

set 집합 { }

순서 X / 중복 X / 집합 연산 O
중복 제거, 교집합·합집합·차집합 연산에 사용.
인덱스 접근 불가.
예: {1, 2, 3, 4}

파이썬 컬렉션 자료형 리스트 딕셔너리 ▲ 파이썬의 네 가지 컬렉션 자료형은 각각 특성이 달라 상황에 맞게 선택해야 한다. 리스트는 순서가 있는 데이터 목록에, 딕셔너리는 키-값 조회에, 집합은 중복 제거와 집합 연산에 적합하다. (출처: Unsplash / 참고 이미지)

📝 list — 리스트 완전 정복

 
list_basic.py — 생성·접근·수정
# 리스트 생성
nums   = [1, 2, 3, 4, 5]
mixed  = [1, "hello", True, 3.14]   # 다양한 타입 혼합 가능
nested = [[1, 2], [3, 4], [5, 6]]  # 중첩 리스트
empty  = []                          # 빈 리스트

# 인덱싱·슬라이싱 (3편 문자열과 동일한 방식)
print(nums[0])        # 1
print(nums[-1])       # 5
print(nums[1:4])      # [2, 3, 4]
print(nums[::-1])     # [5, 4, 3, 2, 1] (뒤집기)

# 값 수정
nums[0] = 10
print(nums)            # [10, 2, 3, 4, 5]

# 중첩 리스트 접근
print(nested[1][0])   # 3  (두 번째 리스트의 첫 번째 요소)

🔨 리스트 메서드 총정리

메서드 설명 예시 / 결과
append(x) 맨 끝에 요소 추가 lst.append(6)
insert(i, x) i번 위치에 x 삽입 lst.insert(0, 99)
extend(iter) 다른 반복가능 객체 이어붙이기 lst.extend([7,8])
remove(x) 값 x 첫 번째 항목 삭제 lst.remove(3)
pop(i=-1) i번 요소 꺼내며 삭제 (기본 마지막) lst.pop() → 마지막값
index(x) x의 첫 번째 인덱스 반환 lst.index(3) → 2
count(x) x 등장 횟수 lst.count(2) → 1
sort() 제자리 정렬 (원본 변경) lst.sort(reverse=True)
sorted(lst) 정렬된 새 리스트 반환 (원본 유지) sorted(lst)
reverse() 제자리 역순 (원본 변경) lst.reverse()
copy() 얕은 복사본 반환 new = lst.copy()
clear() 모든 요소 삭제 lst.clear() → []
 
list_methods.py — 자주 쓰는 메서드
lst = [3, 1, 4, 1, 5, 9, 2]

lst.append(6)           # [3,1,4,1,5,9,2,6]
lst.insert(0, 0)         # [0,3,1,4,1,5,9,2,6]
lst.remove(1)            # 첫 번째 1 삭제 → [0,3,4,1,5,9,2,6]
popped = lst.pop()       # 6 꺼내기 → [0,3,4,1,5,9,2]
print(popped)             # 6

lst.sort()                # [0,1,2,3,4,5,9] (원본 변경)
print(sorted(lst, reverse=True))  # [9,5,4,3,2,1,0] (원본 유지)

# del 키워드로도 삭제 가능
fruits = ["apple", "banana", "cherry"]
del fruits[1]             # banana 삭제
print(fruits)             # ['apple', 'cherry']

# 리스트 연결과 반복
a = [1, 2]
b = [3, 4]
print(a + b)              # [1, 2, 3, 4]
print(a * 3)              # [1, 2, 1, 2, 1, 2]
⚠️ 얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy)
  • b = a → 같은 객체를 가리킴 / a 변경 시 b도 변경됨
  • b = a.copy() 또는 b = a[:] → 얕은 복사 / 1단계 요소는 독립, 중첩 리스트는 공유
  • import copy; b = copy.deepcopy(a) → 깊은 복사 / 완전히 독립된 복사

🔒 tuple — 튜플 완전 정복

 
tuple_example.py
# 튜플 생성 — 소괄호 또는 괄호 없이도 가능
t1 = (1, 2, 3)
t2 = 1, 2, 3         # 괄호 없이도 튜플
t3 = (42,)           # 요소 하나짜리 튜플 — 쉼표 필수!
t4 = (42)            # ← 이건 튜플 아닌 그냥 정수 42

# 인덱싱·슬라이싱 — 리스트와 동일
print(t1[0])         # 1
print(t1[1:3])       # (2, 3)

# 튜플은 수정 불가 → TypeError
# t1[0] = 100     ← TypeError!

# 튜플 언패킹 — 함수 반환값 받을 때 자주 사용
x, y, z = t1
print(x, y, z)       # 1 2 3

# * 연산자로 나머지 모아받기
first, *rest = (1, 2, 3, 4, 5)
print(first)          # 1
print(rest)           # [2, 3, 4, 5]

# 두 변수 값 스왑 — 튜플 언패킹 활용
a, b = 10, 20
a, b = b, a         # temp 변수 없이 스왑!
print(a, b)           # 20 10

# 리스트 ↔ 튜플 변환
lst = list(t1)        # 튜플 → 리스트
tup = tuple(lst)     # 리스트 → 튜플
💡
튜플 vs 리스트 선택 기준 변경이 필요 없는 데이터라면 튜플을 사용하자
  • 튜플 사용 시: 변경되면 안 되는 데이터 (좌표, 설정값, DB 레코드) / 딕셔너리의 키로 사용할 때 (리스트는 키 불가) / 함수에서 여러 값 반환 시
  • 리스트 사용 시: 요소를 추가·삭제·수정해야 할 때 / 순서가 중요한 일반적인 목록
  • 성능: 튜플이 리스트보다 생성 속도가 약간 빠르고 메모리를 적게 씀

🔑 dict — 딕셔너리 완전 정복

 
dict_basic.py — 생성·접근·수정
# 딕셔너리 생성
person = {"name": "Alice", "age": 25, "city": "Seoul"}
empty_d = {}                                  # 빈 딕셔너리
d2 = dict(name="Bob", age=30)                # dict() 생성자

# 값 접근
print(person["name"])          # Alice
print(person.get("age"))       # 25
print(person.get("email"))     # None (키 없어도 오류 없음)
print(person.get("email", "없음"))  # 없음 (기본값 지정)
# person["email"]  → KeyError!

# 추가·수정
person["email"] = "alice@example.com"   # 새 키 추가
person["age"] = 26                       # 기존 값 수정

# 삭제
del person["city"]               # 키-값 삭제
age = person.pop("age")          # 꺼내며 삭제 → age=26

# 키/값/항목 순회
for key in person.keys():         # 키만
    print(key)
for val in person.values():       # 값만
    print(val)
for k, v in person.items():      # 키+값 동시
    print(f"{k}: {v}")

🔨 딕셔너리 유용한 메서드

메서드 설명 반환값
get(key, default) 키로 값 조회 (없으면 default) 값 or None
keys() 모든 키 뷰 반환 dict_keys
values() 모든 값 뷰 반환 dict_values
items() 모든 키-값 쌍 뷰 dict_items
pop(key) 키 꺼내며 삭제
update(dict2) 다른 딕셔너리로 업데이트 None
setdefault(key, val) 키 없을 때만 기본값 설정
copy() 얕은 복사 dict
 
dict_advanced.py — 심화 패턴
# update — 여러 키 한 번에 업데이트 / 병합
d1 = {"a": 1, "b": 2}
d2 = {"b": 99, "c": 3}
d1.update(d2)
print(d1)    # {'a': 1, 'b': 99, 'c': 3}

# 딕셔너리 병합 (Python 3.9+) — | 연산자
merged = {"a": 1} | {"b": 2}
print(merged)   # {'a': 1, 'b': 2}

# in 연산자 — 키 존재 여부 확인
person = {"name": "Alice", "age": 25}
print("name" in person)      # True
print("email" in person)     # False

# setdefault — 없을 때만 기본값 추가 (있으면 그대로)
person.setdefault("city", "Seoul")
person.setdefault("name", "Unknown")  # name 있으므로 변경 안 됨

🔁 set — 집합 완전 정복

 
set_example.py
# 집합 생성 — 중복 자동 제거
s1 = {1, 2, 3, 3, 2}
print(s1)               # {1, 2, 3} (중복 제거, 순서 보장 X)

s2 = set([1, 1, 2, 3])  # 리스트에서 집합 생성
empty_s = set()          # 빈 집합 — {} 쓰면 딕셔너리!

# 활용: 리스트 중복 제거
nums = [1, 2, 2, 3, 3, 3]
unique = list(set(nums))
print(unique)            # [1, 2, 3] (순서 보장 안 됨)

# 집합 연산 — 핵심 기능
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}

print(A | B)             # {1,2,3,4,5,6}  합집합 (union)
print(A.union(B))        # 동일

print(A & B)             # {3, 4}         교집합 (intersection)
print(A.intersection(B)) # 동일

print(A - B)             # {1, 2}         차집합 (difference)
print(A.difference(B))   # 동일

print(A ^ B)             # {1,2,5,6}      대칭차집합

# 포함 관계
print({1, 2}.issubset(A))    # True  ({1,2} ⊆ A)
print(A.issuperset({1, 2}))  # True  (A ⊇ {1,2})
print(A.isdisjoint({5, 6}))  # True  (공통 요소 없음)

# 요소 추가·삭제
s1.add(10)               # 요소 하나 추가
s1.update([20, 30])      # 여러 요소 추가
s1.remove(1)             # 삭제 (없으면 KeyError)
s1.discard(999)          # 삭제 (없어도 오류 없음)

컴프리헨션 — 한 줄로 컬렉션 만들기

컴프리헨션은 for문을 한 줄로 압축해 새 컬렉션을 생성하는 파이썬만의 강력한 문법입니다. 리스트·딕셔너리·집합 모두 지원합니다.

 
comprehension.py
# ① 리스트 컴프리헨션 [표현식 for 변수 in 반복객체 if 조건]
squares   = [x ** 2 for x in range(1, 6)]
print(squares)   # [1, 4, 9, 16, 25]

evens     = [x for x in range(20) if x % 2 == 0]
print(evens)     # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 조건부 표현식 포함 (삼항 연산자와 조합)
labels    = ["짝수" if x % 2 == 0 else "홀수" for x in range(5)]
print(labels)    # ['짝수', '홀수', '짝수', '홀수', '짝수']

# 중첩 컴프리헨션 (2차원 리스트 평탄화)
matrix    = [[1,2,3],[4,5,6],[7,8,9]]
flat      = [n for row in matrix for n in row]
print(flat)      # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# ② 딕셔너리 컴프리헨션 {키: 값 for ...}
sq_dict   = {x: x**2 for x in range(1, 6)}
print(sq_dict)   # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

words     = ["apple", "banana", "cherry"]
len_dict  = {w: len(w) for w in words}
print(len_dict)  # {'apple': 5, 'banana': 6, 'cherry': 6}

# ③ 집합 컴프리헨션 {표현식 for ...}
sq_set    = {x**2 for x in [1,2,3,2,1]}
print(sq_set)    # {1, 4, 9}  (중복 제거)

# ④ 제너레이터 표현식 (괄호) — 메모리 효율적
gen = (x**2 for x in range(10))
print(sum(gen))   # 285  (한 번에 생성 안 하고 필요할 때만)

📝 7편 실습 문제

실습 1 — 단어 빈도 카운터 (딕셔너리)
  • 문장을 단어로 분리해 각 단어의 등장 횟수를 딕셔너리로 만들기
  • 예: "apple banana apple cherry banana apple"{'apple': 3, 'banana': 2, 'cherry': 1}
  • 힌트: setdefault 또는 get 활용 / 딕셔너리 컴프리헨션도 가능
실습 2 — 공통 원소 찾기 (집합)
  • 두 반의 수강생 리스트에서 두 반 모두 수강한 학생 출력 (교집합)
  • 어느 한 반에서만 수강한 학생 출력 (대칭차집합)
 
practice_07.py — 예시 답안
# 실습 1 — 단어 빈도 카운터
sentence = "apple banana apple cherry banana apple"
words    = sentence.split()

# 방법 A: 딕셔너리 직접 구성
counter = {}
for w in words:
    counter[w] = counter.get(w, 0) + 1
print(counter)   # {'apple': 3, 'banana': 2, 'cherry': 1}

# 방법 B: collections.Counter (표준 라이브러리)
from collections import Counter
print(Counter(words))   # Counter({'apple': 3, 'banana': 2, 'cherry': 1})

# 실습 2 — 집합 연산
class_a = {"Alice", "Bob", "Carol", "Dave"}
class_b = {"Bob", "Dave", "Eve", "Frank"}

print("두 반 모두:", class_a & class_b)   # {'Bob', 'Dave'}
print("한 반만:",   class_a ^ class_b)   # {'Alice','Carol','Eve','Frank'}
7편 핵심 요약
  • list [ ]: 순서O 중복O 변경O / append·insert·remove·pop·sort·copy / 슬라이싱 지원
  • tuple ( ): 순서O 중복O 변경X(불변) / 언패킹 / a,b=b,a 스왑 / 딕셔너리 키로 사용 가능
  • dict { }: 키-값 쌍 / Python 3.7+ 삽입 순서 유지 / get()으로 안전하게 조회 / items()로 순회
  • set { }: 순서X 중복X / 빈 집합은 set() / 합집합|·교집합&·차집합-·대칭차집합^
  • 얕은 복사: b = a는 같은 객체 / a.copy()·a[:] 얕은 복사 / deepcopy로 완전 독립
  • 리스트 컴프리헨션: [x**2 for x in range(5) if x%2==0]
  • 딕셔너리 컴프리헨션: {k: v for k, v in items}
  • 집합 컴프리헨션: {x**2 for x in lst} — 중복 자동 제거
  • 제너레이터 표현식: (x**2 for x in range(10)) — 메모리 효율
다음 편 예고 8편 — 파일 입출력 (읽기·쓰기·with문)

open() / read·write·append / with문 / CSV·JSON 파일 다루기

🐍

※ 본 포스팅은 Python 3 공식 문서(docs.python.org)의 Built-in Types 레퍼런스를 기반으로 작성된 학습용 콘텐츠입니다. 코드 예시는 Python 3.10 이상 환경에서 테스트되었습니다.