파이썬에서 Dictionary 란?
Python의 dictionary 는 키-값(key-value) 쌍으로 데이터를 저장하는 대표적인 내장 자료구조입니다.
Python 3.7 이후부터는 삽입 순서(order)도 유지되기 때문에, 리스트나 튜플과는 또 다른 유연한 구조로 활용할 수 있습니다.
my_dict = {
"name": "CIL",
"age": 1,
"site": "Blogger"
}
여기서 "name"
, "age"
, "site"
는 키(key)이고, "CIL"
, 1
, "Blogger"
는 각각의 값(value)입니다.
이처럼 Dictionary는 구조 자체가 명확하여, 의미 전달력과 가독성이 뛰어납니다.
개인적으로 Dictionary를 자주 사용하는 이유
저는 간단한 테스트나 분석용 코드에서 리스트보다 Dictionary를 더 자주 사용합니다.
빠르게 데이터를 구성하고, 특정 항목을 바로 접근하고, 조건문에 활용할 수 있는 구조라서 훨씬 편리하죠.
상용 프로그램이 아닌 경우엔 특히 한 번 실행하고 끝내는 짧은 코드에서 그 진가를 발휘합니다.
Dictionary의 장점
✅ 빠른 데이터 접근
키를 통해 평균 O(1) 시간 복잡도로 데이터에 접근할 수 있습니다. (해시 테이블 기반)
✅ 다양한 값 저장 가능
문자열, 숫자, 리스트, 또 다른 딕셔너리 등 다양한 자료형을 값으로 저장할 수 있습니다.
✅ 가독성 높은 구조
key-value 쌍으로 되어 있어 데이터의 의미를 명확하게 표현할 수 있습니다.
✅ 동적 수정 용이
데이터의 추가, 삭제, 수정이 직관적이고 쉬워서 실시간 관리에 유리합니다.
Dictionary의 단점
❌ 메모리 사용량
해시 기반 구조이기 때문에 리스트보다 메모리를 더 많이 사용합니다.
❌ 키 제한
키는 반드시 **해시 가능한 타입(immutable)**이어야 하며, 리스트 같은 가변 객체는 키로 쓸 수 없습니다.
❌ 순서 변경 불가
삽입 순서는 유지되지만, 그 순서를 사용자가 직접 재정렬할 수는 없습니다.
❌ 중복 키 허용 불가
같은 키를 두 번 선언하면, 마지막 값만 유지됩니다.
example = {"key": 1, "key": 2}
print(example) # {'key': 2}
Dictionary 활용 코드 예시
my_dict = {"name": "CIL", "age": 1, "site": "Blogger"}
# 값 출력
print(my_dict["name"]) # CIL
print(my_dict["age"]) # 1
# 값 추가 및 수정
my_dict["email"] = "cil@blogger.com"
my_dict["age"] = 2
# 값 삭제
del my_dict["site"]
print(my_dict) # {'name': 'CIL', 'age': 2, 'email': 'cil@blogger.com'}
# 반복문 활용
for key in my_dict:
print(key)
for value in my_dict.values():
print(value)
for key, value in my_dict.items():
print(f"{key}: {value}")
# 키 존재 여부 확인
if "name" in my_dict:
print("Name in dictionary")
# 안전한 접근
major = my_dict.get("major", "Undeclared")
print(major) # Undeclared
# 키가 없을 경우 기본값 추가
graduation_year = my_dict.setdefault("graduation_year", 2024)
print(graduation_year)
print(my_dict)
문자열 처리 예시 – 단어 수 세기
text = "hello world hello"
word_count = {}
for word in text.split():
word_count[word] = word_count.get(word, 0) + 1
print(word_count) # {'hello': 2, 'world': 1}
실제 경험에서 느낀 점
뉴스 제목에서 단어 유사도를 분석하기 위해 PyTorch나 TensorFlow로 벡터화를 시도했는데, 프로그램이 너무 무거워졌습니다.
그래서 일단 Dictionary로 유사도를 흉내 내보려고 했지만, 결국 Dictionary 역시 메모리를 많이 사용하는 구조라 프로그램이 무거워지는 문제는 해결되지 않았습니다.
단어 벡터화를 통해 유사도를 계산하는 방법은
- Vector Space 모델
- Normed Space
- Hilbert Space 등 다양한 기법이 존재합니다.
하지만 이는 별도의 심화 주제로 다루는 게 더 적절할 것 같습니다.
결론: Dictionary는 상황에 따라 최고의 선택지가 될 수 있다
Python의 Dictionary는 다음과 같은 상황에서 탁월한 선택입니다:
- 빠르게 데이터를 구성하고 관리해야 할 때
- 명확한 키 기반으로 접근이 필요한 경우
- 구조적이고 가독성 높은 데이터를 만들고 싶을 때
- 조건별로 데이터를 관리해야 할 때
단, 메모리와 키 구조에 민감한 환경에서는 신중하게 사용해야 한다는 점도 꼭 기억해야 합니다.
대표적인 에러와 해결 방안
1. KeyError
원인: 존재하지 않는 키를 조회할 때 발생
예시:
data = {"name": "Alice"}
print(data["age"]) # KeyError: 'age'
해결 방법:
in
키워드로 키 존재 여부 확인.get()
사용 (없으면None
반환)
if "age" in data:
print(data["age"])
# 또는
print(data.get("age", "기본값")) # "기본값"
2. TypeError: unhashable type
원인: 리스트, 딕셔너리 등 변경 가능한 값을 키로 사용할 때 발생
예시:
my_dict = {[1, 2]: "value"} # TypeError
해결 방법:
- 키는
str
,int
,tuple
등 변경 불가능한 타입만 사용
my_dict = {(1, 2): "value"} # OK
3. AttributeError: 'dict' object has no attribute ...
원인: 딕셔너리는 data.key
처럼 속성 접근이 안 됨
예시:
data = {"name": "Bob"}
print(data.name) # AttributeError
해결 방법:
data["name"]
처럼 대괄호로 접근
print(data["name"]) # OK
4. ValueError
(변환 관련)
원인: dict로 변환할 수 없는 구조
예시:
dict([1, 2, 3]) # ValueError
해결 방법:
(key, value)
쌍의 리스트로 전달해야 함
dict([("a", 1), ("b", 2)]) # OK
5. 반복문에서 RuntimeError: dictionary changed size during iteration
원인: 딕셔너리를 반복 중에 변경할 때
예시:
my_dict = {"a": 1, "b": 2}
for k in my_dict:
my_dict["c"] = 3 # RuntimeError
해결 방법:
list(my_dict)
처럼 복사본을 사용
for k in list(my_dict):
my_dict["c"] = 3
6. 중첩 딕셔너리 접근 오류
원인: 하위 키가 없을 때
예시:
data = {"user": {}}
print(data["user"]["name"]) # KeyError
해결 방법:
.get()
중첩 사용 또는dict.get("key", {})
name = data.get("user", {}).get("name", "Unknown")
보너스 팁: defaultdict
사용하기
문제:
d = {}
d["x"] += 1 # KeyError
해결:
from collections import defaultdict
d = defaultdict(int)
d["x"] += 1 # OK