Post

[Python] 자료구조 완전 정리: List/Tuple/Dict/Set

[Python] 자료구조 완전 정리: List/Tuple/Dict/Set

파이썬 자료구조는 처음에 서로 헷갈릴 수밖에 없습니다. 특히 코딩 테스트에서는 어떤 주머니(자료구조)에 데이터를 넣느냐에 따라 속도가 천차만별이기 때문에, 쓰임새를 확실히 구분하는 게 중요합니다.


1. 파이썬 4대 자료구조: 모양 · 특징 · 코테용 필살기

1) 리스트 [ ] (List) : “순서가 중요한 데이터 나열”

가장 기본이 되는 상자입니다. 넣는 순서대로 번호(인덱스)가 매겨집니다.

  • 모양: 대괄호 [1, 2, 3]
  • 특징: 수정 가능, 중복 허용, 순서 있음
  • 코테용 필살기:
    • 데이터를 그냥 저장하고 순서대로 꺼낼 때
    • 정렬(sort())이 필요할 때
  • 단점: 특정 값이 들어있는지 찾을 때(in) 처음부터 끝까지 다 뒤져야 해서 느림 ($O(N)$)

📌 리스트 주요 메서드 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 추가/삭제
arr = [1, 2, 3]
arr.append(4)          # [1, 2, 3, 4]
arr.pop()              # [1, 2, 3] (마지막 요소 제거)
arr.pop(0)             # [2, 3] (인덱스 지정 삭제)

# 확장 & 정렬
arr.extend([5, 6])     # [2, 3, 5, 6]
arr.sort()             # [2, 3, 5, 6]
arr.reverse()          # [6, 5, 3, 2]

# 슬라이싱/복사
sub = arr[1:3]         # [5, 3]

# 멤버십 테스트 (느림)
if 5 in arr:
    print("있음")

2) 튜플 ( ) (Tuple) : “절대 안 변하는 읽기 전용 묶음”

리스트와 비슷하지만, 한 번 만들면 내용을 절대 못 바꿉니다.

  • 모양: 소괄호 (1, 2) (괄호 없이 1, 2라고만 써도 튜플이 됨)
  • 특징: 수정 불가, 중복 허용, 순서 있음
  • 코테용 필살기:
    • 좌표값 처리: (x, y)처럼 묶어서 다닐 때
    • 딕셔너리의 키: 리스트는 딕셔너리의 키가 못 되지만, 튜플은 가능

📌 튜플 주요 특징 & 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 생성
point = (3, 4)
coord = 3, 4         # 괄호 생략 가능

# 언패킹 (함수 반환값 받기 등)
x, y = point

# 변환
lst = list(point)    # [3, 4]

t = (1, 2, 3)
print(t[0])          # 1
print(t.count(2))    # 1
print(t.index(3))    # 2

3) 딕셔너리 { : } (Dictionary) : “이름표 붙은 데이터”

단어장에서 단어를 찾으면 뜻이 나오듯, Key를 주면 Value가 나옵니다.

  • 모양: 중괄호 + 콜론 {"name": "Gemini", "age": 1}
  • 특징: Key는 중복 불가, 순서 없음(최신 파이썬은 순서 유지하지만 없다고 생각하는 게 안전)
  • 코테용 필살기:
    • 빈도수 세기: {"A": 3, "B": 5}처럼 개수 셀 때 최고
    • 데이터 검색: 아무리 데이터가 많아도 Key만 알면 즉시($O(1)$) 찾음

📌 딕셔너리 주요 메서드 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 기본 구조
scores = {"A": 90, "B": 80}

# get: 없으면 기본값
print(scores.get("C", 0))  # 0

# setdefault: 없으면 추가, 있으면 그대로
scores.setdefault("C", 70)

# pop: 값 반환 후 삭제
b_score = scores.pop("B")  # 80

# popitem: 마지막 추가된 (키, 값) 튜플 반환 후 삭제
k, v = scores.popitem()

# update: 여러 개 추가/업데이트
scores.update({"A": 95, "D": 60})

# defaultdict: 기본값 자동 생성
from collections import defaultdict
cnt = defaultdict(int)
cnt["x"] += 1

4) 셋 { } (Set) : “중복 없는 집합”

딕셔너리에서 Key만 모아놓은 형태라고 볼 수 있습니다.

  • 모양: 중괄호 {1, 2, 3} (주의: 빈 셋은 set()으로 선언)
  • 특징: 중복 절대 불가, 순서 없음
  • 코테용 필살기:
    • 중복 제거: list(set(nums)) 한 줄이면 중복 끝
    • 기록 확인: “나 이거 본 적 있나?” 체크할 때 리스트보다 압도적으로 빠름 ($O(1)$)

📌 셋 주요 메서드 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
s = {1, 2, 3}

# 추가/삭제
s.add(4)
s.remove(3)      # 없으면 KeyError
s.discard(5)       # 없어도 에러 없음
s.pop()            # 임의의 요소 하나 제거 (반환)

# 집합 연산
s1 = {1, 2, 3}
s2 = {2, 3, 4}
print(s1 | s2)     # 합집합 {1,2,3,4}
print(s1 & s2)     # 교집합 {2,3}
print(s1 - s2)     # 차집합 {1}

# 중복 제거
unique = list(set([1, 2, 2, 3]))

2. 💡 한눈에 보는 핵심 비교표

구분리스트 []튜플 ()딕셔너리 { : }{ }
수정 가능OXOO
중복 허용OO(Key는 X)X
검색 속도느림 ($O(N)$)느림 ($O(N)$)매우 빠름 ($O(1)$)매우 빠름 ($O(1)$)
주요 용도데이터 보관/정렬좌표/불변 데이터개수 세기/ID 검색중복 제거/방문 체크

3. 시간 복잡도 비교 & 코테 추천 시나리오

3.1. 주요 연산별 시간 복잡도

연산리스트튜플딕셔너리
인덱스 접근 / 키 조회$O(1)$$O(1)$$O(1)$$O(1)$
순차 탐색 / 멤버십 (in)$O(N)$$O(N)$$O(1)$$O(1)$
삽입 (끝)$O(1)$ 평균-$O(1)$$O(1)$
삽입 (중간)$O(N)$-$O(1)$$O(1)$
삭제 (끝)$O(1)$-$O(1)$$O(1)$
삭제 (중간/키)$O(N)$-$O(1)$$O(1)$

✅ 코테에서 가장 자주 쓰는 패턴: 멤버십 체크 + 중복 제거dict / set으로 해결하세요.

3.2. 실전 사용 추천 시나리오

  • 정렬된 순서 유지하면서 데이터를 쌓고 싶을 때list + append / sort
  • 순서를 바꾸면 안 되는 고정된 값(좌표, 쌍) 관리tuple
  • 빈도수 세기 / ID → 정보 매핑dict (Counter로 더 쉽게)
  • 중복 제거 / 방문 여부 검사set (in이 $O(1)$이기 때문에 리스트보다 훨씬 빠름)
  • 입력 순서 유지하면서 키-값 저장OrderedDict (파이썬 3.7 이상은 기본 dict도 유지됨)
  • 기본값이 있는 딕셔너리를 자주 쓸 때defaultdict

4. 고급 자료구조 / 유용한 표준 라이브러리

4.1. defaultdict (기본값 자동 생성)

collections.defaultdict는 키가 없을 때 자동으로 기본값을 만들어줍니다.

1
2
3
4
5
6
7
from collections import defaultdict

cnt = defaultdict(int)  # 기본값 0
cnt["a"] += 1

lst = defaultdict(list)
lst["a"].append(1)

4.2. Counter (빈도수 세기 최적화)

collections.Counter는 데이터를 넣고 바로 개수를 셀 때 유용합니다.

1
2
3
4
5
6
from collections import Counter

words = ["a", "b", "a", "c", "b"]
count = Counter(words)
print(count)            # Counter({'a': 2, 'b': 2, 'c': 1})
print(count.most_common(2))  # [('a', 2), ('b', 2)]

4.3. OrderedDict (순서가 중요할 때)

파이썬 3.7+에서는 기본 dict도 입력 순서를 유지하지만, OrderedDict는 추가 기능(이동, 마지막 삭제 등)을 제공합니다.

1
2
3
4
5
6
from collections import OrderedDict

o = OrderedDict()
o["a"] = 1
o["b"] = 2
o.move_to_end("a")  # 'a'를 맨 뒤로 이동

4.4. dataclasses (값 객체 정의)

dataclasses.dataclass는 간단한 데이터 구조를 선언할 때 매우 편리합니다.

1
2
3
4
5
6
7
8
9
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

p = Point(1, 2)
print(p)  # Point(x=1, y=2)

5. {}의 정체: 딕셔너리 vs 셋

파이썬에서 중괄호 {}를 볼 때 헷갈리기 쉬운 곳입니다.

  • a = {} : 빈 딕셔너리 생성 (파이썬의 약속)
  • b = set() : 빈 생성
  • c = {1, 2} : 값이 하나씩 있으면
  • d = {1: "A"} : Key: Value 쌍이 있으면 딕셔너리

{} 안에 :이 있으면 딕셔너리, 없으면 셋이라고 생각하면 쉽습니다.


4. 파이썬 자료구조 잘 쓰는 법 (코딩 테스트 필살기)

4.1. + vs .append() vs .add(): 언제 쓰나?

연산대상원본 변경설명
+리스트/튜플/문자열X두 덩어리를 붙여 새 객체 생성
.append(x)리스트O리스트 맨 뒤에 요소 추가
.add(x)O셋에 요소 추가 (중복이면 무시)
dict[k] = v딕셔너리O키로 값 저장/업데이트

4.2. 실전 선택 가이드

  1. 순서가 중요하고, 정렬/정렬 검사가 필요하다list = [] + append
  2. 중복 체크/멤버십 테스트가 자주 필요하다seen = set() + add (멤버십은 $O(1)$)
  3. 좌표나 복합 키로 방문 체크하고 싶다(x, y) 튜플 + 딕셔너리 키
  4. 값의 빈도수를 빠르게 구하고 싶다counts = {} + counts[val] = counts.get(val, 0) + 1

5. Set (집합) 상세 정리

5.1. 핵심 개념: “중복 없음, 순서 없음”

  • Unique: 동일한 값을 두 번 넣어도 하나만 남음 (중복 자동 제거)
  • Unordered: 순서를 보장하지 않음 (인덱스로 접근 불가)
  • Hashable: 내부적으로 해시 테이블을 사용해 검색 속도가 압도적으로 빠름

5.2. 선언 및 기본 조작

1
2
3
4
5
6
7
8
9
# 선언
s = {1, 2, 3, 3, 3}  # s는 {1, 2, 3}
empty_set = set()    # 빈 셋 ({}는 빈 딕셔너리)

# 추가 및 삭제
s.add(4)             # 요소 하나 추가
s.update([5, 6])     # 여러 요소 한꺼번에 추가
s.remove(1)          # 요소 삭제 (없으면 에러)
s.discard(10)        # 요소 삭제 (없어도 에러 안 남)

5.3. 집합 연산 (수학적 활용)

연산기호메서드설명
합집합a | ba.union(b)두 집합의 모든 원소 (중복 제외)
교집합a & ba.intersection(b)공통된 원소만
차집합a - ba.difference(b)a에는 있고 b에는 없는 것
대칭 차집합a ^ ba.symmetric_difference(b)둘 중 한 곳에만 있는 것

5.4. 코딩 테스트 필살기

① 중복 제거

1
2
nums = [1, 2, 2, 3, 4, 4, 4, 5]
unique_nums = list(set(nums))  # [1, 2, 3, 4, 5]

② 멤버십 테스트 (검색 최적화)

  • List: 처음부터 끝까지 확인 ($O(N)$)
  • Set: 해시로 즉시 확인 ($O(1)$)

주의: 셋에 넣는 원소는 값이 변하지 않는(Immutable) 녀석이어야 합니다. 그래서 (r, c, num)처럼 튜플을 넣는 것이 안전합니다.


6. 요약: 어떤 자료구조를 선택할까?

자료구조모양수정 가능중복검색 속도주요 용도
List[ ]OO$O(N)$데이터 나열, 정렬, 스택/큐
Tuple( )XO$O(N)$좌표, 딕셔너리 키, 불변 데이터
Dict{ : }O(Key는 X)$O(1)$빈도수 계산, 매핑
Set{ }OX$O(1)$중복 제거, 방문 체크

7. 한 줄 꿀팁

  1. 빈 셋s = set() ( {}는 빈 딕셔너리 )
  2. 수정하고 싶으면 [], 불변이면 ( )
  3. 빠른 검색이 필요하면 리스트 대신 { } (셋/딕셔너리)
  4. 리스트append, add, 딕셔너리dict[key] = value

이제 파이썬 자료구조를 보고 “어떤 주머니에 넣으면 좋을까”를 빠르게 판단할 수 있을 거예요. 이 내용을 TIL로 잘 보관해 두면, 코딩 테스트 중에도 머리가 덜 복잡해질 거예요! ✨

This post is licensed under CC BY 4.0 by the author.