들어가며
파이썬 리스트 외에도 배열 데이터를 처리할 수 있는 구조들이 더 있는데요. 리스트와 유사한 성격을 가지는 파이썬 데이터 구조는 딕셔너리와 튜플 외에도 여러 가지가 있습니다. 각 데이터 구조는 고유한 특성을 가지고 있으며, 상황에 따라 적절한 데이터 구조를 선택한다면 좀 더 쾌적한 프로그래밍에 도움이 될 것입니다.
리스트와 유사한 성격을 가지는 다른 데이터 구조들과 그 성격에 대해 알아보도록 하겠습니다.
파이썬 데이터 구조의 활용
1. 집합 (Set)
집합은 고유한 요소들의 무순서 컬렉션입니다. 중복을 허용하지 않으며, 요소의 존재 여부를 빠르게 확인할 수 있습니다. 또한, 집합은 수학적 집합 연산(합집합, 교집합 등)을 효율적으로 수행할 수 있습니다.
numbers = {1, 2, 3, 4, 5}
print(numbers) # {1, 2, 3, 4, 5}
numbers.add(6)
print(numbers) # {1, 2, 3, 4, 5, 6}
# 중복된 값을 추가해도 변경되지 않음
numbers.add(3)
print(numbers) # {1, 2, 3, 4, 5, 6}
특징
- 중복 요소 제거: 자동으로 중복된 요소를 제거합니다.
- 빠른 검색: 요소의 존재 여부를 O(1) 시간에 확인할 수 있습니다.
- 수학적 연산: 합집합, 교집합, 차집합 등의 집합 연산을 간편하게 수행할 수 있습니다.
2. frozenset
frozenset은 불변 집합입니다. 일반 집합과 동일한 특성을 가지지만, 한 번 정의된 후에는 변경할 수 없습니다. 이는 데이터의 불변성을 요구하는 상황에서 유용하게 사용할 수 있습니다.
immutable_set = frozenset([1, 2, 3, 4, 5])
print(immutable_set) # frozenset({1, 2, 3, 4, 5})
# 요소를 추가하려고 하면 오류 발생
# immutable_set.add(6) # AttributeError: 'frozenset' object has no attribute 'add'
특징
- 불변성: 생성된 후 요소를 추가하거나 제거할 수 없습니다.
- 데이터 보호: 데이터의 무결성을 유지해야 하는 경우에 유용합니다.
- 딕셔너리 키: 집합을 딕셔너리의 키로 사용할 수 있습니다.
3. 배열 (Array)
배열은 리스트와 유사하지만, 고정된 타입의 요소를 가집니다. 주로 숫자 데이터를 효율적으로 저장하고 처리하는 데 사용됩니다. 배열은 리스트보다 메모리 사용량이 적고, 연산이 빠릅니다.
import array
numbers = array.array('i', [1, 2, 3, 4, 5])
print(numbers) # array('i', [1, 2, 3, 4, 5])
numbers.append(6)
print(numbers) # array('i', [1, 2, 3, 4, 5, 6])
특징
- 고정된 타입: 모든 요소가 동일한 데이터 타입을 가져야 합니다.
- 메모리 효율성: 동일한 타입의 데이터를 다룰 때 메모리 사용을 최적화할 수 있습니다.
- 빠른 연산: 숫자 연산에 특화된 작업에서 빠르게 처리할 수 있습니다.
4. deque (Double-Ended Queue)
deque는 양쪽 끝에서 빠르게 요소를 추가하고 제거할 수 있는 큐입니다. 리스트와 달리, 양쪽 끝에서의 삽입과 삭제가 O(1) 시간에 가능합니다.
from collections import deque
d = deque([1, 2, 3, 4, 5])
d.append(6)
d.appendleft(0)
print(d) # deque([0, 1, 2, 3, 4, 5, 6])
d.pop()
print(d) # deque([0, 1, 2, 3, 4, 5])
d.popleft()
print(d) # deque([1, 2, 3, 4, 5])
특징
- 빠른 삽입과 삭제: 리스트와 달리 양쪽 끝에서의 삽입과 삭제가 빠릅니다.
- 큐 및 스택: 양방향 접근이 가능하여 큐와 스택 모두 구현할 수 있습니다.
- 메모리 효율성: 리스트보다 효율적으로 메모리를 사용합니다.
5. 문자열 (String)
입문자들은 문자열 처리 방법에서 신기해 하는 분들이 많습니다. 문자열은 문자들의 불변 시퀀스입니다. 리스트처럼 인덱싱과 슬라이싱이 가능하며, 다양한 문자열 메서드를 사용할 수 있습니다.
text = "Hello, World!"
print(text[0]) # H
print(text[7:12]) # World
print(text.lower()) # hello, world!
print(text.upper()) # HELLO, WORLD!
특징
- 불변성: 문자열은 불변 객체로, 생성된 후 수정할 수 없습니다.
- 다양한 메서드: 문자열 조작을 위한 다양한 메서드를 제공합니다.
- 슬라이싱: 리스트와 유사하게 슬라이싱이 가능합니다.
6. NamedTuple
namedtuple은 튜플처럼 동작하지만, 필드에 이름을 부여할 수 있습니다. 이는 코드의 가독성을 높여주며, 튜플의 불변성과 동일한 이점을 가집니다.
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p.x) # 1
print(p.y) # 2
특징
- 가독성: 필드 이름을 통해 데이터 구조를 명확하게 표현할 수 있습니다.
- 불변성: 튜플의 불변성과 동일한 이점을 가집니다.
- 메모리 효율성: 클래스보다 메모리를 덜 사용합니다.
7. 데이터프레임 (DataFrame)
pandas 라이브러리의 DataFrame은 2차원 레이블이 지정된 데이터 구조로, 엑셀 스프레드시트와 유사합니다. 데이터 분석 및 조작에 매우 유용합니다.
import pandas as pd
data = {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}
df = pd.DataFrame(data)
print(df)
# name age
# 0 Alice 25
# 1 Bob 30
# 2 Charlie 35
특징
- 데이터 분석: 대규모 데이터의 분석 및 조작에 최적화되어 있습니다.
- 표형 데이터 처리: 행과 열로 구성된 데이터를 처리하는 데 적합합니다.
- 다양한 기능: 데이터 정제, 변환, 집계 등의 다양한 기능을 제공합니다.
이 데이터 구조들은 리스트와 유사한 기능을 제공하면서도 고유한 특성과 장점을 가지고 있습니다. 각각의 상황에 맞게 적절한 데이터 구조를 선택한다면 좀 더 효율적인 프로그래밍을 할 수 있죠.
마무리
리트스와 유사하면서도 각각의 특징이 살아있는 여러 데이터 구조들에 대해 알아보았습니다. 각각의 특징을 잘 살려 적재 적소에 사용한다면 프로그래밍도 쉬워지고, 데이터 처리에서도 좀더 좋은 성능을 기대할 수 있겠죠.
오늘의 지식은 도움이 좀 되셨나요? 여러분들의 프로그래밍에 오늘도 도움이 되는 정보가 되었길 바라며 글을 마치겠습니다.