4대 컬렉션 자료형(리스트, 튜플, 집합, 딕셔너리) 총정리

앞서 파이썬의 제어 구조(조건문과 반복문)를 통해 프로그램의 흐름을 제어하는 방법을 배웠습니다. 이번 글에서는 파이썬에서 데이터를 효율적으로 조직하고 대량으로 저장할 수 있는 4가지 핵심 컬렉션 자료형(Collection Data Types)의 모든 것을 완벽하게 파헤쳐 보겠습니다.

1. 파이썬 컬렉션 자료형 개요

파이썬은 데이터를 모아서 관리할 수 있는 강력한 내장 컬렉션 구조를 제공합니다. 각 자료형의 변경 가능성(Mutability), 순서(Order), 중복 허용 여부에 따라 적절한 자료형을 선택하는 것이 중요합니다.

자료형 변경 가능성 (Mutability) 순서 (Order) 중복 허용 표기 용도 및 특징
리스트 (List) 변경 가능 (Mutable) 순서 있음 (Ordered) 허용 [] 순서가 중요하고 요소를 자주 추가·삭제·수정할 때
튜플 (Tuple) 변경 불가능 (Immutable) 순서 있음 (Ordered) 허용 () 데이터가 변하지 않아야 하며 안전하게 유지할 때
집합 (Set) 변경 가능 (Mutable) 순서 없음 (Unordered) 불가 (고유값) {} 중복 제거 및 수학적 집합 연산이 필요할 때
딕셔너리 (Dict) 변경 가능 (Mutable) 순서 있음 (Ordered) 키 불가, 값 허용 {} 키(Key)와 값(Value)의 쌍으로 데이터를 저장할 때

2. 리스트 (List)

리스트는 가장 널리 사용되는 가변(mutable) 시퀀스 자료형입니다. 서로 다른 데이터 타입을 혼합하여 저장할 수 있습니다.

2.1 리스트 생성 및 인덱싱

대괄호 []를 사용하여 생성하며, 0부터 시작하는 인덱스로 요소에 접근합니다. 

 
# 다양한 리스트 생성
numbers = [1, 2, 3, 4, 5]
mixed_list = [1, "hello", 3.14, True]
nested_list = [1, [2, 3], [4, 5]] # 중첩 리스트

# 인덱싱과 슬라이싱
a = [10, 20, 30, 40, 50]
print(a[0])    # 첫 번째 요소: 10
print(a[-1])   # 마지막 요소: 50
print(a[1:4])  # 슬라이싱: [20, 30, 40]

2.2 리스트 주요 메서드 (추가, 수정, 삭제, 정렬)

  • 추가: append()(마지막 추가), insert(index, value)(특정 위치 추가), extend()(리스트 병합)

  • 수정: 인덱스 또는 슬라이싱 범위를 지정하여 값 변경 (a[1] = 99)

  • 삭제: del a[index], a.remove(value)(첫 번째 일치 값 삭제), a.pop()(마지막 요소 반환 후 삭제), a.clear()

  • 정렬 및 기타: a.sort(), a.reverse(), a.count(value), a.index(value)

# 리스트 추가 및 정렬 예시
a = [3, 1, 4, 2]
a.append(5)     # [3, 1, 4, 2, 5]
a.sort()        # 오름차순 정렬: [1, 2, 3, 4, 5]
a.sort(reverse=True) # 내림차순 정렬

2.3 리스트 복사와 리스트 컴프리헨션

  • 참조 vs 복사: b = a와 같이 대입하면 객체의 메모리 주소가 공유되므로 원본이 함께 변경됩니다. 독립적인 복사를 원할 때는 copy() 메서드나 list() 함수를 사용해야 합니다. 

     
    a = ["apple", "banana"]
    b = a.copy() # 독립된 복사본 생성
    

  • 리스트 컴프리헨션 (List Comprehension): 반복문과 조건문을 한 줄로 결합하여 간결하게 새로운 리스트를 생성합니다.

    fruits = ["apple", "banana", "cherry", "kiwi"]
    # 이름에 'a'가 포함된 과일만 추출
    newlist = [x for x in fruits if "a" in x]
    

3. 튜플 (Tuple)

튜플은 리스트와 유사하지만 한 번 생성되면 요소를 변경할 수 없는 불변(Immutable) 객체입니다. 데이터의 안전한 보호와 메모리 효율성이 장점입니다.

3.1 튜플 생성 시 주의사항

소괄호 ()를 사용하며, 요소가 단 1개일 때는 반드시 뒤에 쉼표(,)를 붙여야 튜플로 인식됩니다. (쉼표만 있어도 튜플 생성 가능)

t1 = (1,)     # 요소가 1개인 튜플 (쉼표 필수!)
t2 = 1, 2, 3  # 괄호 생략 가능 (패킹)

3.2 패킹과 언패킹 (Packing & Unpacking)

튜플은 여러 값을 한 번에 묶거나(패킹), 여러 변수에 나누어 담는(언패킹) 기능이 매우 직관적입니다. 함수의 리턴값으로 여러 데이터를 보낼 때 유용합니다.

# 튜플 언패킹
fruits = ("apple", "banana", "cherry")
(green, yellow, red) = fruits

# 함수에서 여러 값 반환하기
वों def get_min_max(numbers):
    return (min(numbers), max(numbers))

low, high = get_min_max([10, 50, 20, 5])

4. 집합 (Set)

집합은 중복을 허용하지 않고, 순서가 없는(Unordered) 데이터 구조입니다. 순서가 없기 때문에 인덱싱을 지원하지 않습니다.

4.1 집합 생성 및 중복 제거

# 중복된 요소를 자동으로 제거
s1 = {1, 2, 2, 3, 4, 4, 5}
print(s1) # {1, 2, 3, 4, 5}

# 빈 집합 생성은 set()을 사용해야 함 ({}는 딕셔너리로 인식)
empty_set = set()

4.2 강력한 수학적 집합 연산

파이썬 집합은 데이터 간의 관계를 분석할 때 유용한 연산자들을 기본 제공합니다.

s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}

print(s1 & s2)          # 교집합 (Intersection): {4, 5}
print(s1 | s2)          # 합집합 (Union): {1, 2, 3, 4, 5, 6, 7, 8}
print(s1 - s2)          # 차집합 (Difference): {1, 2, 3}
print(s1 ^ s2)          # 대칭차집합 (Symmetric Difference): {1, 2, 3, 6, 7, 8}

# 요소 추가 및 제거 메서드
s1.add(10)
s1.remove(1) # 없으면 오류 발생
s1.discard(99) # 없어도 오류 발생 안 함

5. 딕셔너리 (Dictionary)

딕셔너리는 키(Key)와 값(Value)의 쌍으로 이루어진 해시 맵(Hash Map) 구조입니다. 키는 고유하며 중복될 수 없지만, 값은 중복될 수 있습니다.

5.1 딕셔너리 생성 및 값 접근

중괄호 {}를 사용하며, 키를 통해 값에 빠르게 접근할 수 있습니다. 키가 존재하지 않을 때 에러를 방지하려면 .get() 메서드를 사용하는 것이 안전합니다.

# 딕셔너리 생성
person = {'name': 'Alice', 'age': 25, 'city': 'Seoul'}

# 값 접근
print(person['name'])       # 출력: Alice
print(person.get('phone'))  # 키가 없으면 None 반환 (에러 없음)

# 데이터 추가 및 수정
person['email'] = 'alice@email.com' # 추가
person['age'] = 26                  # 수정
person.update({'age': 27, 'city': 'Busan'}) # 일괄 수정/추가

5.2 딕셔너리 순회 및 활용

.keys(), .values(), .items() 메서드를 활용하여 반복문과 함께 유연하게 데이터를 조회할 수 있습니다.

scores = {'math': 90, 'english': 85, 'science': 95}

# 키와 값 동시 순회
for subject, score in scores.items():
    print(f"{subject} 과목 점수: {score}점")

5.3 딕셔너리 항목 삭제

pop(), del, popitem(), clear() 등의 메서드로 항목을 안전하게 제거할 수 있습니다.

d4 = {1: '서울', 2: '부산', 3: '대구', 4: '대전'}

print(d4.pop(2))    # 키 '2'에 해당하는 값을 가져오면서 삭제 (출력: 부산)
del d4[3]           # 키 '3' 직접 삭제
print(d4.popitem()) # 마지막 항목을 가져오면서 삭제
d4.clear()          # 모든 항목 비우기 (빈 딕셔너리 유지)

5.4 딕셔너리 복사 시 주의사항 (copy()와 dict())

리스트와 마찬가지로, dict2 = dict1처럼 단순 대입 연산자를 사용하는 것은 실제 객체가 복사되는 것이 아니라 메모리 주소(참조)만 복사되는 것입니다. 따라서 dict1의 내용을 수정하면 dict2의 내용도 함께 변경되므로 주의해야 합니다.

완전히 독립된 복사본을 만들려면 copy() 메서드나 dict() 생성자를 사용해야 합니다.

# 잘못된 복사 방식 (참조 공유 발생)
a = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
b = a # b는 a를 참조할 뿐입니다.

a["year"] = 2024
print(b["year"]) # 출력: 2024 (a를 바꿨는데 b도 함께 바뀜!)

# 올바른 복사 방식 1: copy() 메서드 사용
b = a.copy()

# 올바른 복사 방식 2: dict() 함수 사용
c = dict(a)

답글 남기기