자료구조

1. 개요

파이썬은 다양한 내장 자료구조를 제공하여 데이터를 효율적으로 관리할 수 있게 한다.

주요 자료구조는 List, Dictionary, Tuple, Set이 있다.

 

2. List(리스트)

리스트는 파이썬에서 가장 기본적이고 많이 사용되는 자료구조이다.

동적 배열로 구현되어 있어 메모리에 연속적으로 저장된다.

 

2.1. 기본 사용법

선언

list = []

 

ex)

# 리스트 선언
empty_list = []
numbers = [1, 2, 3, 4, 5]
mixed_list = [1, \"Hello\", 3.14, True]

# 인덱싱 (0부터 시작)
print(numbers[0])  # 출력: 1
print(numbers[-1])  # 출력: 5 (뒤에서부터 첫 번째 요소)

# 슬라이싱 (범위 지정)
print(numbers[1:3])  # 출력: [2, 3] (인덱스 1부터 2까지)
print(numbers[:2])   # 출력: [1, 2] (처음부터 인덱스 1까지)
print(numbers[2:])   # 출력: [3, 4, 5] (인덱스 2부터 끝까지)

 

리스트는 인덱싱과 슬라이싱을 통해 요소에 접근할 수 있으며, 음수 인덱스를 사용하여 뒤에서부터 접근할 수도 있다.

 

2.2. 메서드

메서드 설명 반환값
append(x) 리스트 끝에 요소 추가 None
insert(i, x) 지정된 위치에 요소 삽입 None
extend(iterable) 다른 이터러블의 모든 요소를 리스트에 추가 None
remove(x) 첫 번째로 나타나는 값 제거 None
pop([i]) 지정한 위치(기본값은 마지막)의 요소 제거 후 반환 제거된 요소
clear() 모든 요소 제거 None
index(x) 값이 첫 번째로 나타나는 인덱스 반환 인덱스
count(x) 값이 나타나는 횟수 반환 정수
sort(key=None, reverse=False) 리스트 정렬 (제자리) None
reverse() 요소 순서 뒤집기 (제자리) None
copy() 리스트의 얕은 복사본 반환 새 리스트

 

반환값이 없는 함수(None을 반환하는 함수)는 in-place 수정 메서드로 원본 리스트를 직접 수정한다.

이는 "명시적인 것이 암시적인 것보다 낫다"는 파이썬의 설계 철학을 반영한다.

 

2.3. 리스트 컴프리헨션

파이썬 리스트의 강력한 기능 중 하나는 리스트 컴프리헨션으로, 간결하게 리스트를 생성할 수 있다.

 

ex)

# 일반적인 방법
squares = []
for i in range(10):
    squares.append(i ** 2)
print(squares)  # 출력: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 리스트 컴프리헨션 사용
squares = [i ** 2 for i in range(10)]
print(squares)  # 출력: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 조건부 리스트 컴프리헨션
even_squares = [i ** 2 for i in range(10) if i % 2 == 0]
print(even_squares)  # 출력: [0, 4, 16, 36, 64]

 

 

3. Dictionary(딕셔너리)

딕셔너리는 키-값 쌍을 저장하는 자료구조이다.

해시 테이블로 구현되어 있어 키를 통한 값 접근이 O(1) 시간 복잡도를 가진다.

 

3.1. 기본 사용법

선언

dictionary = {}

 

ex)

# 딕셔너리 선언
empty_dict = {}
person = {'name': '홍길동', 'age': 30, 'city': '서울'}

# 값 접근
print(person['name'])  # 출력: 홍길동

# 값 수정
person['age'] = 31
print(person)  # 출력: {'name': '홍길동', 'age': 31, 'city': '서울'}

# 새 키-값 쌍 추가
person['job'] = '개발자'
print(person)  # 출력: {'name': '홍길동', 'age': 31, 'city': '서울', 'job': '개발자'}

 

딕셔너리는 키를 통해 값에 접근하며, 키는 변경 불가능한 타입(문자열, 숫자, 튜플 등)이어야 한다.

 

3.2. 메서드

메서드 설명 반환값
get(key[, default]) 키에 해당하는 값을 반환, 없으면 기본값(기본값 없으면 None) 반환 값 또는 기본값
keys() 모든 키를 포함하는 뷰 반환 dict_keys 객체
values() 모든 값을 포함하는 뷰 반환 dict_values 객체
items() 모든 (키, 값) 쌍을 포함하는 뷰 반환 dict_items 객체
pop(key[, default]) 키에 해당하는 값을 제거하고 반환, 없으면 기본값 반환(기본값 없으면 KeyError) 제거된 값
update([other]) 다른 딕셔너리의 키-값 쌍으로 딕셔너리 업데이트 None
clear() 모든 키-값 쌍 제거 None

 

get() 메서드는 일반 인덱싱(dict[key])과 달리 키가 없을 때 예외를 발생시키지 않고 None이나 지정된 기본값을 반환한다.

파이썬 3.7부터 딕셔너리는 삽입 순서를 보존한다. 즉, 키를 추가한 순서대로 순회할 수 있다.

 

3.3. 딕셔너리 컴프리헨션

리스트 컴프리헨션과 유사하게, 딕셔너리도 컴프리헨션을 지원한다.

 

ex)

# 숫자의 제곱을 값으로 갖는 딕셔너리 생성
squares = {x: x**2 for x in range(6)}
print(squares)  # 출력: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 조건부 딕셔너리 컴프리헨션
even_squares = {x: x**2 for x in range(6) if x % 2 == 0}
print(even_squares)  # 출력: {0: 0, 2: 4, 4: 16}

# 문자열에서 문자와 개수 매핑
word = \"mississippi\"
char_count = {char: word.count(char) for char in set(word)}
print(char_count)  # 출력: {'p': 2, 's': 4, 'i': 4, 'm': 1}

 

 

 

4. Tuple(튜플)

튜플은 순서가 있는 불변(immutable) 시퀀스로, 한 번 생성되면 값을 변경할 수 없다.

 

4.1. 기본 사용법

선언

tuple = ()

 

ex)

# 튜플 선언
empty_tuple = ()
single_item = (1,)  # 단일 요소 튜플은 뒤에 콤마를 붙여야 함
numbers = (1, 2, 3, 4, 5)
mixed_tuple = (1, \"Hello\", 3.14)

# 괄호 없이도 튜플 생성 가능
another_tuple = 1, 2, 3, 4, 5

# 인덱싱 및 슬라이싱 (리스트와 동일)
print(numbers[0])    # 출력: 1
print(numbers[1:3])  # 출력: (2, 3)

# 변수 할당 (언패킹)
a, b, c = (1, 2, 3)
print(a, b, c)  # 출력: 1 2 3

 

튜플은 리스트와 유사한 인덱싱과 슬라이싱을 지원하지만, 값을 변경하는 메서드(append, insert 등)는 지원하지 않는다.

 

4.2. 튜플의 활용

튜플은 여러 변수에 값을 동시에 할당하거나, 함수에서 여러 값을 반환할 때 유용하게 사용된다.

 

ex)

# 튜플 언패킹을 이용한 변수 교환
a, b = 10, 20
a, b = b, a
print(a, b)  # 출력: 20 10

# 함수에서 여러 값 반환
def get_dimensions():
    return 1920, 1080

width, height = get_dimensions()
print(f\"너비: {width}, 높이: {height}\")  # 출력: 너비: 1920, 높이: 1080

# 튜플을 이용한 반복
points = [(0, 0), (1, 2), (3, 5), (6, 8)]
for x, y in points:
    print(f\"x = {x}, y = {y}\")

 

튜플은 불변성으로 인해 딕셔너리의 키나 집합의 요소로 사용할 수 있다.

 

 

5. Set(집합)

집합은 중복이 없는 요소들의 모음으로, 수학의 집합 개념을 구현한 자료구조이다.

데이터 순서를 보장하지 않으며, 해시 테이블을 기반으로 구현되어 있다.

 

5.1. 기본 사용법

선언

set = set()

 

ex)

# 집합 선언
empty_set = set()  # 주의: {}는 빈 딕셔너리를 생성함
numbers = {1, 2, 3, 4, 5}
fruits = {\"apple\", \"banana\", \"orange\", \"apple\"}  # 중복 요소는 자동으로 제거됨

print(fruits)  # 출력: {'apple', 'banana', 'orange'} (순서는 보장되지 않음)

# 요소 추가
fruits.add(\"grape\")
print(fruits)  # 출력: {'apple', 'banana', 'orange', 'grape'}

# 요소 제거
fruits.remove(\"banana\")  # 요소가 없으면 KeyError 발생
print(fruits)  # 출력: {'apple', 'orange', 'grape'}

fruits.discard(\"melon\")  # 요소가 없어도 에러 발생하지 않음

 

집합은 요소의 존재 여부를 O(1) 시간 복잡도로 확인할 수 있어 멤버십 테스트에 효율적이다.

 

5.2. 집합 연산

파이썬 집합은 수학의 집합 연산을 직관적으로 구현할 수 있다.

 

ex)

a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}

# 합집합
print(a | b)  # 출력: {1, 2, 3, 4, 5, 6, 7, 8}
print(a.union(b))  # 위와 동일

# 교집합
print(a & b)  # 출력: {4, 5}
print(a.intersection(b))  # 위와 동일

# 차집합
print(a - b)  # 출력: {1, 2, 3}
print(a.difference(b))  # 위와 동일

# 대칭 차집합 (합집합 - 교집합)
print(a ^ b)  # 출력: {1, 2, 3, 6, 7, 8}
print(a.symmetric_difference(b))  # 위와 동일

# 부분집합 확인
c = {1, 2}
print(c.issubset(a))  # 출력: True
print(c <= a)  # 위와 동일

# 상위집합 확인
print(a.issuperset(c))  # 출력: True
print(a >= c)  # 위와 동일

 

집합 연산은 데이터 처리나 알고리즘 구현에서 매우 유용하게 활용된다.

 

5.3. 집합 컴프리헨션

집합도 컴프리헨션을 지원한다.

 

ex)

# 집합 컴프리헨션
squares = {x**2 for x in range(10)}
print(squares)  # 출력: {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

# 조건부 집합 컴프리헨션
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(even_squares)  # 출력: {0, 4, 16, 36, 64}

# 문자열에서 고유한 소문자 추출
sentence = \"The Quick Brown Fox Jumps Over The Lazy Dog\"
lowercase_letters = {char.lower() for char in sentence if char.isalpha()}
print(lowercase_letters)  # 모든 알파벳 소문자가 포함됨

 

집합 컴프리헨션은 중복 제거와 변환을 동시에 수행할 때 유용하다.

 

 

6. 자료구조 변환

파이썬에서는 자료구조 간의 변환이 매우 간단하다.

 

ex)

# 문자열 -> 리스트
s = \"Hello\"
l = list(s)
print(l)  # 출력: ['H', 'e', 'l', 'l', 'o']

# 리스트 -> 튜플
t = tuple(l)
print(t)  # 출력: ('H', 'e', 'l', 'l', 'o')

# 리스트 -> 집합 (중복 제거)
chars = ['H', 'e', 'l', 'l', 'o']
s = set(chars)
print(s)  # 출력: {'e', 'H', 'l', 'o'}

# 튜플 -> 리스트
t = (1, 2, 3)
l = list(t)
print(l)  # 출력: [1, 2, 3]

# 다양한 자료구조를 이용한 딕셔너리 생성
keys = [\"a\", \"b\", \"c\"]
values = [1, 2, 3]
d = dict(zip(keys, values))
print(d)  # 출력: {'a': 1, 'b': 2, 'c': 3}

 

이러한 변환 기능은 데이터 처리 과정에서 필요에 따라 적절한 자료구조로 쉽게 전환할 수 있게 해준다.

 

 

7. 파이썬 자료구조 특성 비교

특성 List Dictionary Tuple Set
변경 가능성 가변(mutable) 가변(mutable) 불변(immutable) 가변(mutable)
순서 순서 보장 순서 보장(3.7+) 순서 보장 순서 보장 안 함
인덱싱 지원 키로 접근 지원 지원 안 함
중복 요소 허용 키 중복 불가 허용 허용 안 함
용도 순서 있는 컬렉션 키-값 매핑 불변 데이터 그룹 고유 요소 집합
시간 복잡도(검색) O(n) O(1) O(n) O(1)
시간 복잡도(삽입) O(1) *중간삽입은 O(n) O(1) 변경 불가 O(1)
메모리 효율성 보통 낮음 높음 보통

 

'학습 > Python' 카테고리의 다른 글

표준 입출력 및 문자열 포맷팅  (0) 2025.04.29
조건문, 반복문  (1) 2025.04.25
파이썬의 특징과 철학  (0) 2025.04.18
문자열(String)  (0) 2025.04.14
연산자, 연산 함수, math, random 모듈  (0) 2025.04.14