Python에서 딕셔너리를 사용하면 키와 값의 쌍을 효율적으로 관리할 수 있지만, 복잡한 데이터 구조를 다룰 때는 딕셔너리를 중첩해서 사용하는 경우가 많습니다. 중첩된 딕셔너리나 다차원 딕셔너리를 조작할 때는 일반적인 딕셔너리 조작과는 다른 공략이 필요합니다. 본 기사에서는 Python에서 중첩된 딕셔너리를 효율적으로 조작하는 방법에 대해 기본부터 응용까지 쉽게 설명합니다. 이를 통해 대량의 데이터나 복잡한 구조를 다룰 때 유용한 지식을 습득할 수 있습니다.
딕셔너리의 중첩이란?
딕셔너리의 중첩은 딕셔너리의 값으로 다른 딕셔너리를 포함하는 구조를 말합니다. 이러한 데이터 구조는 계층적인 데이터를 표현하거나 관련된 데이터를 그룹화할 때 유용합니다.
중첩된 딕셔너리의 기본 구조
다음은 전형적인 중첩된 딕셔너리의 예입니다:
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
이 경우, data
는 최상위 딕셔너리이며, 각 키(person1
또는 person2
)에 관련된 값으로 또 다른 딕셔너리가 포함되어 있습니다.
중첩 딕셔너리의 용도 예시
- 사용자 정보 관리
사용자별로 다른 정보를 묶을 때 유용합니다.
users = {
"user1": {"email": "user1@example.com", "is_active": True},
"user2": {"email": "user2@example.com", "is_active": False},
}
- 계층 데이터 표현
계층 구조를 가진 데이터(예: 카테고리와 서브카테고리)를 표현할 수 있습니다.
categories = {
"Fruits": {"Citrus": ["Orange", "Lemon"], "Berries": ["Strawberry", "Blueberry"]},
"Vegetables": {"Leafy": ["Spinach", "Lettuce"], "Root": ["Carrot", "Potato"]},
}
중첩 딕셔너리는 매우 유연성이 높고, 복잡한 데이터를 쉽게 다룰 수 있지만, 그만큼 조작에 주의가 필요합니다. 다음 섹션에서는 중첩된 딕셔너리로 접근하는 방법에 대해 자세히 살펴보겠습니다.
중첩된 딕셔너리에 접근하는 방법
중첩된 딕셔너리를 조작하려면 여러 개의 키를 사용하여 값을 접근해야 합니다. Python에서는 키를 순차적으로 지정하여 값을 가져오는 것이 기본입니다.
기본적인 접근 방법
중첩된 딕셔너리의 값에 접근하려면 키를 체인처럼 나열하여 작성합니다. 아래 예시에서는 2단계 값에 접근하는 방법을 보여줍니다.
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
# Alice의 이름을 가져오기
name = data["person1"]["name"]
print(name) # 출력: Alice
# Bob의 나이를 가져오기
age = data["person2"]["age"]
print(age) # 출력: 25
존재하지 않는 키에 주의
지정한 키가 딕셔너리 내에 존재하지 않으면, KeyError
가 발생합니다.
# 존재하지 않는 키를 지정
print(data["person3"]["name"]) # KeyError: 'person3'
깊은 중첩 접근
더 깊게 중첩된 딕셔너리에도 동일한 방법으로 접근할 수 있지만, 코드가 길어져 가독성이 떨어질 수 있습니다.
deep_data = {
"level1": {
"level2": {
"level3": {"key": "value"}
}
}
}
# "value"에 접근
value = deep_data["level1"]["level2"]["level3"]["key"]
print(value) # 출력: value
딕셔너리 내포 표기법을 사용한 접근
여러 값을 효율적으로 가져오려면, 딕셔너리 내포 표기법을 활용할 수도 있습니다.
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
# 모든 사람의 이름을 가져오기
names = {key: value["name"] for key, value in data.items()}
print(names) # 출력: {'person1': 'Alice', 'person2': 'Bob'}
다음 섹션에서는 get()
을 사용한 안전한 접근 방법에 대해 설명합니다. 이를 통해 존재하지 않는 키로 인한 오류를 방지할 수 있습니다.
get()을 사용한 안전한 접근 방법
중첩된 딕셔너리에 접근할 때, 지정한 키가 존재하지 않으면 오류를 피할 수 있는 방법으로 get()
메서드가 유용합니다. 이 메서드는 키가 없을 경우 오류를 발생시키지 않고, 기본값을 반환합니다.
기본적인 사용 예시
다음은 get()
을 사용한 안전한 접근 방법의 예시입니다.
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
# 존재하는 키에 접근
name = data.get("person1", {}).get("name", "Unknown")
print(name) # 출력: Alice
# 존재하지 않는 키에 접근
name = data.get("person3", {}).get("name", "Unknown")
print(name) # 출력: Unknown
이 방법을 사용하면 get()
을 연속적으로 사용하여 안전하게 중첩된 딕셔너리에 접근할 수 있습니다.
기본값 설정하기
get()
의 두 번째 인수로 기본값을 설정할 수 있습니다. 기본값을 설정하면, 키가 없을 경우 오류가 발생하는 대신 지정한 값이 반환됩니다.
# 키가 없을 경우 기본값을 반환
age = data.get("person3", {}).get("age", 0)
print(age) # 출력: 0
여러 키에 대한 접근을 쉽게 하는 함수
중첩된 딕셔너리를 자주 조작하는 경우, 접근을 쉽게 하기 위해 함수를 만드는 것이 유용합니다.
def safe_get(dictionary, keys, default=None):
for key in keys:
dictionary = dictionary.get(key, {})
if not isinstance(dictionary, dict):
return default
return dictionary or default
# 사용 예시
data = {
"level1": {"level2": {"level3": {"key": "value"}}}
}
value = safe_get(data, ["level1", "level2", "level3", "key"], "Not Found")
print(value) # 출력: value
# 존재하지 않는 키를 지정
missing = safe_get(data, ["level1", "level4", "key"], "Not Found")
print(missing) # 출력: Not Found
딕셔너리가 존재하지 않을 경우 처리 방법
중첩된 딕셔너리 내에 딕셔너리가 아닌 값이 있을 가능성이 있는 경우, get()
을 사용하면 타입 에러도 피할 수 있습니다.
data = {
"person1": {"name": "Alice", "age": 30},
"person2": "Invalid Data"
}
# 딕셔너리가 아닌 데이터를 안전하게 처리
age = data.get("person2", {}).get("age", "Unknown")
print(age) # 출력: Unknown
이렇게 get()
을 사용하면 중첩된 딕셔너리에서도 안전하게 값을 얻을 수 있으며, 코드의 견고성이 향상됩니다. 다음 섹션에서는 defaultdict
을 사용하여 중첩 딕셔너리를 자동으로 생성하는 방법에 대해 설명합니다.
defaultdict로 중첩 딕셔너리 만들기
중첩된 딕셔너리를 다룰 때, 접근하기 전에 키를 수동으로 초기화하는 것은 번거롭습니다. collections
모듈의 defaultdict
을 사용하면 키의 존재 여부를 신경 쓰지 않고 중첩 딕셔너리를 동적으로 생성할 수 있습니다.
defaultdict란?
defaultdict
은 기본값을 가지는 딕셔너리로, 존재하지 않는 키에 접근하면 자동으로 초기값을 생성합니다. 중첩된 딕셔너리를 다룰 때는 이 특성을 이용해 계층 구조를 쉽게 만들 수 있습니다.
기본적인 사용 예시
다음 예시는 defaultdict
을 사용하여 중첩된 딕셔너리를 생성하는 방법입니다.
from collections import defaultdict
# 중첩된 딕셔너리를 생성하기 위한 defaultdict
nested_dict = defaultdict(dict)
# 값 대입
nested_dict["person1"]["name"] = "Alice"
nested_dict["person1"]["age"] = 30
nested_dict["person2"]["name"] = "Bob"
# 결과 확인
print(nested_dict)
# 출력: defaultdict(, {'person1': {'name': 'Alice', 'age': 30}, 'person2': {'name': 'Bob'}})
존재하지 않는 키에 접근하면 새로운 딕셔너리가 자동으로 생성되므로 사전에 초기화할 필요가 없습니다.
다차원 딕셔너리 만들기
더 깊은 계층의 딕셔너리를 만들려면 defaultdict
을 중첩하여 사용할 수 있습니다.
from collections import defaultdict
# 자동으로 계층을 생성하는 중첩된 딕셔너리
nested_dict = defaultdict(lambda: defaultdict(dict))
# 값 대입
nested_dict["level1"]["level2"]["key"] = "value"
# 결과 확인
print(nested_dict)
# 출력: defaultdict( at 0x...>, {'level1': defaultdict(, {'level2': {'key': 'value'}})})
이렇게 각 계층이 자동으로 초기화되므로 코드 작성이 간편해집니다.
defaultdict의 단점
- 기존 딕셔너리와의 호환성
defaultdict
은 일반 딕셔너리와 다르기 때문에 다른 함수나 라이브러리(예:json
모듈)로 전달할 때 일반 딕셔너리로 변환해야 할 수 있습니다.
import json
# 일반 딕셔너리로 변환
normal_dict = dict(nested_dict)
print(json.dumps(normal_dict, indent=2))
- 예기치 않은 키 생성
존재하지 않는 키에 접근하면 빈 딕셔너리가 자동으로 생성됩니다. 이 동작이 불필요한 경우 주의가 필요합니다.
용도 예시: 카운트 및 집계
defaultdict
은 중첩된 카운트 처리나 집계 처리에도 적합합니다.
from collections import defaultdict
# 카운트용 중첩 딕셔너리
counts = defaultdict(lambda: defaultdict(int))
# 데이터 카운트
data = [("person1", "apple"), ("person1", "banana"), ("person2", "apple")]
for person, fruit in data:
counts[person][fruit] += 1
# 결과 확인
print(counts)
# 출력: defaultdict( at 0x...>, {'person1': {'apple': 1, 'banana': 1}, 'person2': {'apple': 1}})
defaultdict
을 사용하면 중첩 딕셔너리의 생성과 조작이 효율화되고, 코드가 간결해집니다. 다음 섹션에서는 다차원 딕셔너리를 초기화하는 방법과 그 구체적인 예시를 소개합니다.
다차원 딕셔너리 초기화 및 조작
다차원 딕셔너리의 초기화에는 Python의 리스트 내포 표기법이나 딕셔너리 내포 표기법을 사용하면 효율적입니다. 또한, 초기화 후의 조작 방법도 이해해 두면 복잡한 데이터 구조를 원활하게 관리할 수 있습니다.
다차원 딕셔너리 수동 초기화
수동으로 다차원 딕셔너리를 초기화하려면, 중첩된 구조를 만들어야 합니다.
data = {
"level1": {
"level2": {
"key1": 0,
"key2": 0
}
}
}
# 값 변경
data["level1"]["level2"]["key1"] = 42
print(data)
# 출력: {'level1': {'level2': {'key1': 42, 'key2': 0}}}
수동 초기화는 간단하지만, 구조가 복잡해질수록 중복이 많아질 수 있습니다.
딕셔너리 내포 표기법을 사용한 효율적인 초기화
딕셔너리 내포 표기법을 사용하면 계층적인 딕셔너리를 간결하게 초기화할 수 있습니다.
# 3차원 딕셔너리 초기화
data = {
f"level1_{i}": {
f"level2_{j}": {f"key_{k}": 0 for k in range(3)}
for j in range(2)
}
for i in range(2)
}
print(data)
# 출력 예: {'level1_0': {'level2_0': {'key_0': 0, 'key_1': 0, 'key_2': 0}, ...}}
이 방법을 사용하면 동적인 키와 값을 쉽게 생성할 수 있습니다.
다차원 딕셔너리에 동적 값 추가하기
새로운 키나 값을 동적으로 추가하려면, 딕셔너리 조작의 기본 메서드를 활용합니다.
data = {"level1": {}}
# 동적으로 값 추가
data["level1"]["level2"] = {"key1": 42, "key2": 100}
print(data)
# 출력: {'level1': {'level2': {'key1': 42, 'key2': 100}}}
전체 계층 조작 방법
다차원 딕셔너리 내 모든 요소를 조작하려면, 루프나 재귀를 사용합니다.
def print_nested_dict(d, level=0):
for key, value in d.items():
print(" " * level + f"{key}: {value if not isinstance(value, dict) else ''}")
if isinstance(value, dict):
print_nested_dict(value, level + 1)
# 실행 예
print_nested_dict(data)
# 출력:
# level1:
# level2:
# key1: 42
# key2: 100
딕셔너리 내포 표기법으로 값 변환하기
기존의 다차원 딕셔너리를 조작하여 값을 변환할 수도 있습니다.
data = {"level1": {"level2": {"key1": 1, "key2": 2}}}
# 값을 2배로 변환
transformed_data = {
k1: {k2: {k3: v * 2 for k3, v in v2.items()} for k2, v2 in v1.items()}
for k1, v1 in data.items()
}
print(transformed_data)
# 출력: {'level1': {'level2': {'key1': 2, 'key2': 4}}}
자동 초기화와 조작 결합하기
동적 구조를 쉽게 초기화하고 조작하려면 defaultdict
이나 딕셔너리 내포 표기법을 결합하면 유용합니다.
from collections import defaultdict
# 자동 초기화
data = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
# 값 대입
data["level1"]["level2"]["key1"] += 10
data["level1"]["level2"]["key2"] += 20
print(data)
# 출력: defaultdict( at 0x...>, {'level1': defaultdict(...)}))
효율적인 초기화와 조작 방법을 이해함으로써, 복잡한 다차원 딕셔너리 관리가 쉬워집니다. 다음 섹션에서는 중첩된 딕셔너리의 업데이트와 추가에 대한 자세한 설명을 제공합니다.
중첩된 딕셔너리 업데이트 및 추가 방법
중첩된 딕셔너리에서는 특정 키의 값을 변경하거나 새로운 키와 값을 추가하는 작업이 자주 발생합니다. 이 섹션에서는 효율적으로 업데이트나 추가를 수행하는 방법을 설명합니다.
값 업데이트
기존 값을 업데이트하려면 키를 지정하고 값을 할당합니다. 중첩된 딕셔너리에서는 계층을 따라가며 원하는 값을 지정합니다.
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
# 값 업데이트
data["person1"]["age"] = 31
print(data)
# 출력: {'person1': {'name': 'Alice', 'age': 31}, 'person2': {'name': 'Bob', 'age': 25}}
새로운 키와 값 추가
딕셔너리에 존재하지 않는 키를 지정하면 새로운 키와 그 값을 추가할 수 있습니다.
# 새로운 키와 값 추가
data["person3"] = {"name": "Charlie", "age": 22}
print(data)
# 출력: {'person1': {...}, 'person2': {...}, 'person3': {'name': 'Charlie', 'age': 22}}
딕셔너리 merge로 일괄 업데이트
Python 3.9 이상에서는 |=
연산자를 사용하여 딕셔너리를 병합하고 일괄적으로 업데이트할 수 있습니다.
updates = {"person1": {"age": 32}, "person4": {"name": "Diana", "age": 28}}
# 병합하여 업데이트
data |= updates
print(data)
# 출력: {'person1': {'age': 32}, 'person2': {...}, 'person3': {...}, 'person4': {'name': 'Diana', 'age': 28}}
계층을 확인하며 업데이트
키의 존재를 확인하면서 업데이트하려면 if
문이나 get()
을 사용할 수 있습니다.
if "person2" in data:
data["person2"]["age"] += 1
else:
data["person2"] = {"age": 1}
print(data)
# 출력: {'person1': {...}, 'person2': {'name': 'Bob', 'age': 26}, ...}
중첩 딕셔너리 자동 생성 활용하여 추가
중첩된 딕셔너리의 깊은 계층에 새로운 키를 추가할 때 collections.defaultdict
을 사용하면 효율적입니다.
from collections import defaultdict
# 자동 초기화
data = defaultdict(lambda: defaultdict(dict))
# 깊은 계층에 추가
data["person1"]["address"]["city"] = "New York"
data["person1"]["address"]["zip"] = "10001"
print(data)
# 출력: defaultdict(, {'person1': {'address': {'city': 'New York', 'zip': '10001'}}})
재귀적으로 딕셔너리 업데이트 함수
중첩된 딕셔너리 전체를 업데이트하려면 재귀 함수를 사용하면 유용합니다.
def update_nested_dict(original, updates):
for key, value in updates.items():
if isinstance(value, dict) and key in original:
update_nested_dict(original[key], value)
else:
original[key] = value
# 사용 예
data = {"level1": {"level2": {"key1": "value1"}}}
updates = {"level1": {"level2": {"key2": "value2"}, "level3": {"key3": "value3"}}}
update_nested_dict(data, updates)
print(data)
# 출력: {'level1': {'level2': {'key1': 'value1', 'key2': 'value2'}, 'level3': {'key3': 'value3'}}}
에러 방지를 고려한 업데이트
키가 존재하지 않을 경우의 에러를 방지하려면 예외 처리를 활용하는 방법도 있습니다.
try:
data["person4"]["age"] = 35
except KeyError:
data["person4"] = {"age": 35}
print(data)
# 출력: {'person1': {...}, 'person2': {...}, 'person3': {...}, 'person4': {'age': 35}}
중첩된 딕셔너리의 업데이트 및 추가 방법을 이해하면 데이터를 효율적이고 유연하게 처리할 수 있습니다. 다음 섹션에서는 에러 처리에 대해 자세히 설명합니다.
중첩된 딕셔너리 처리 시 에러 처리
중첩된 딕셔너리를 조작할 때 발생할 수 있는 일반적인 에러를 적절히 처리하는 것은 안정적인 코드를 작성하는 데 중요합니다. 특히, 키의 존재나 데이터 타입 불일치로 인한 에러를 방지하는 방법에 대해 설명합니다.
일반적인 에러 및 원인
- KeyError
존재하지 않는 키에 접근할 때 발생합니다.
data = {"level1": {"level2": {"key": "value"}}}
print(data["level1"]["level3"]) # KeyError: 'level3'
- AttributeError
부적절한 타입의 데이터에 딕셔너리 작업을 적용할 때 발생합니다.
에러 처리 기본: get()으로 안전한 접근
get()
을 사용하면 키가 존재하지 않을 경우 기본값을 반환하여 KeyError
를 피할 수 있습니다.
data = {"level1": {"level2": {"key": "value"}}}
# 존재하지 않는 키에도 안전하게 접근
value = data.get("level1", {}).get("level3", "default")
print(value) # 출력: default
예외 처리로 유연한 대응
예외 처리를 사용하면 에러 발생 시 동작을 제어할 수 있습니다.
data = {"level1": {"level2": {"key": "value"}}}
try:
value = data["level1"]["level3"]["key"]
except KeyError:
value = "default"
except TypeError:
value = "invalid type"
print(value) # 출력: default
재귀적 에러 처리
깊은 중첩 딕셔너리를 다룰 때 에러를 피하기 위한 범용 함수를 작성할 수 있습니다.
def safe_get(dictionary, keys, default=None):
for key in keys:
try:
dictionary = dictionary[key]
except (KeyError, TypeError):
return default
return dictionary
# 사용 예
data = {"level1": {"level2": {"key": "value"}}}
print(safe_get(data, ["level1", "level2", "key"], "default")) # 출력: value
print(safe_get(data, ["level1", "level3", "key"], "default")) # 출력: default
타입 체크 활용
isinstance()
을 사용하여 타입을 확인함으로써 타입 에러를 방지할 수 있습니다.
data = {"level1": {"level2": {"key": "value"}}}
if isinstance(data.get("level1", None), dict):
print(data["level1"].get("level2", {}).get("key", "default"))
else:
print("Invalid data structure")
# 출력: value
자동으로 초기화되는 딕셔너리로 에러 방지
collections.defaultdict
을 사용하면 존재하지 않는 키가 자동으로 초기화되므로 에러를 방지할 수 있습니다.
from collections import defaultdict
data = defaultdict(lambda: defaultdict(dict))
data["level1"]["level2"]["key"] = "value"
# 존재하지 않는 키에도 에러 없이 접근
print(data["level1"]["level3"]["key"]) # 출력: {}
에러 메시지 로깅
에러를 잡아서 로그를 남기면 디버깅이나 문제 해결이 용이해집니다.
import logging
logging.basicConfig(level=logging.ERROR)
try:
value = data["level1"]["level3"]["key"]
except KeyError as e:
logging.error(f"KeyError: {e}")
value = "default"
print(value) # 출력: default
데이터 검증의 중요성
딕셔너리 작업 전에 예상되는 데이터 구조를 확인하는 것도 유효합니다.
def validate_data_structure(data):
if not isinstance(data, dict):
raise ValueError("Data must be a dictionary")
return True
try:
validate_data_structure(data)
except ValueError as e:
print(e)
에러 처리를 잘 활용하면 코드의 안정성과 신뢰성을 높일 수 있습니다. 다음 섹션에서는 중첩된 딕셔너리 작업에 유용한 라이브러리에 대해 설명합니다.
딕셔너리를 효율적으로 조작하는 라이브러리
Python에서는 중첩된 딕셔너리를 효율적으로 조작할 수 있는 유용한 라이브러리가 여러 가지 있습니다. 이 섹션에서는 pandas
와 json
모듈을 비롯한 딕셔너리 작업을 간소화하는 도구들을 소개합니다.
pandas로 딕셔너리 조작
pandas
라이브러리는 딕셔너리를 데이터프레임으로 변환하여 조작할 때 매우 유용합니다. 특히 중첩된 딕셔너리를 행렬 형식으로 처리할 때 유용합니다.
import pandas as pd
# 딕셔너리를 데이터프레임으로 변환
data = {
"person1": {"name": "Alice", "age": 30},
"person2": {"name": "Bob", "age": 25},
}
df = pd.DataFrame.from_dict(data, orient="index")
print(df)
# 출력:
# name age
# person1 Alice 30
# person2 Bob 25
이 방법을 사용하면 딕셔너리 내 계층을 쉽게 조작할 수 있으며, 열이나 행으로 데이터를 필터링하거나 정렬할 수 있습니다.
json 모듈을 사용한 조작
json
모듈은 딕셔너리를 JSON 형식의 데이터와 상호 변환하는 데 사용됩니다. 딕셔너리를 파일에 저장하거나 외부 데이터를 읽어와 중첩 딕셔너리로 처리할 때 유용합니다.
import json
# 딕셔너리를 JSON 문자열로 변환
data_json = json.dumps(data, indent=2)
print(data_json)
# JSON 문자열을 딕셔너리로 변환
loaded_data = json.loads(data_json)
print(loaded_data)
또한 중첩된 딕셔너리를 쉽게 다루기 위한 데이터 가공에도 사용됩니다.
dictdiffer로 딕셔너리 차이 계산
dictdiffer
라이브러리를 사용하면 중첩 딕셔너리의 차이를 쉽게 계산할 수 있습니다. 데이터 변경 사항을 탐지할 때 유용합니다.
from dictdiffer import diff
data1 = {"person1": {"name": "Alice", "age": 30}}
data2 = {"person1": {"name": "Alice", "age": 31}}
# 차이 계산
difference = list(diff(data1, data2))
print(difference)
# 출력: [('change', 'person1.age', (30, 31))]
toolz로 중첩 딕셔너리 조작
toolz
라이브러리에는 중첩 딕셔너리를 효율적으로 조작할 수 있는 함수가 풍부하게 준비되어 있습니다.
from toolz.dicttoolz import get_in, assoc_in
data = {"level1": {"level2": {"key": "value"}}}
# 중첩 딕셔너리에서 안전하게 값 가져오기
value = get_in(["level1", "level2", "key"], data)
print(value) # 출력: value
# 중첩 딕셔너리에 값 설정
new_data = assoc_in(data, ["level1", "level2", "new_key"], "new_value")
print(new_data)
# 출력: {'level1': {'level2': {'key': 'value', 'new_key': 'new_value'}}}
flatdict로 중첩 해제
flatdict
라이브러리는 중첩된 딕셔너리를 평탄화하여 작업을 단순화합니다.
import flatdict
data = {"level1": {"level2": {"key1": "value1", "key2": "value2"}}}
# 중첩 해제
flat_data = flatdict.FlatDict(data)
print(flat_data)
# 출력: FlatDict({'level1:level2:key1': 'value1', 'level1:level2:key2': 'value2'})
# 평탄화된 데이터를 딕셔너리로 복원
nested_data = flat_data.as_dict()
print(nested_data)
deepmerge로 딕셔너리 병합
deepmerge
라이브러리를 사용하면 복잡한 중첩 딕셔너리를 쉽게 병합할 수 있습니다.
from deepmerge import always_merger
dict1 = {"level1": {"key1": "value1"}}
dict2 = {"level1": {"key2": "value2"}}
# 중첩 딕셔너리 병합
merged = always_merger.merge(dict1, dict2)
print(merged)
# 출력: {'level1': {'key1': 'value1', 'key2': 'value2'}}
이 라이브러리들을 활용하면 중첩된 딕셔너리를 효율적으로 조작하고 복잡한 데이터 구조도 쉽게 다룰 수 있습니다. 다음 섹션에서는 지금까지 소개한 내용을 총정리합니다.
결론
이번 글에서는 Python에서 중첩된 딕셔너리나 다차원 딕셔너리를 효율적으로 조작하는 방법을 설명했습니다. 기본적인 접근 방법부터 안전한 접근, 자동 초기화 및 에러 처리까지, 중첩 딕셔너리 관리를 간단하게 만드는 방법을 폭넓게 소개했습니다. 또한 pandas
, json
, toolz
와 같은 유용한 라이브러리를 활용하여 복잡한 작업을 간소화하는 방법도 배웠습니다.
이 지식을 활용하면 대규모 및 계층적인 데이터를 다룰 때 유연성 및 효율성이 크게 향상됩니다. 중첩된 딕셔너리는 Python에서 강력한 데이터 구조 중 하나입니다. 실습을 통해 그 잠재력을 최대한 활용해 보세요.
- TypeError
중첩된 딕셔너리의 중간에 딕셔너리가 아닌 타입에 접근할 때 발생합니다.
data = {"level1": "not a dict"}
print(data["level1"]["level2"]) # TypeError: string indices must be integers