있다 잠재적 인 문제 당신이 당신의 자신의 재귀 구현 또는 스택 반복 동등한를 작성하는 경우는. 이 예를 참조하십시오.
dic = {}
dic["key1"] = {}
dic["key1"]["key1.1"] = "value1"
dic["key2"] = {}
dic["key2"]["key2.1"] = "value2"
dic["key2"]["key2.2"] = dic["key1"]
dic["key2"]["key2.3"] = dic
정상적인 의미에서 중첩 사전은 데이터 구조와 같은 n-nary 트리가됩니다. 그러나 정의 는 교차 가장자리 또는 심지어 뒤쪽 가장자리의 가능성을 배제하지 않습니다 (따라서 더 이상 나무가 아닙니다). 예를 들어, 여기 key2.2 에서 사전에 보유하고 키 1 , key2.3의 전체 사전에 점 (후면 가장자리 / 사이클). 백 엣지 (사이클)가 있으면 스택 / 재귀가 무한히 실행됩니다.
root<-------back edge
/ \ |
_key1 __key2__ |
/ / \ \ |
|->key1.1 key2.1 key2.2 key2.3
| / | |
| value1 value2 |
| |
cross edge----------|
Scharron 에서이 구현으로이 사전을 인쇄하면
def myprint(d):
for k, v in d.items():
if isinstance(v, dict):
myprint(v)
else:
print "{0} : {1}".format(k, v)
이 오류가 표시됩니다.
RuntimeError: maximum recursion depth exceeded while calling a Python object
senderle 의 구현도 마찬가지 입니다.
마찬가지로 Fred Foo의 다음 구현으로 무한 루프를 얻습니다 .
def myprint(d):
stack = list(d.items())
while stack:
k, v = stack.pop()
if isinstance(v, dict):
stack.extend(v.items())
else:
print("%s: %s" % (k, v))
그러나 Python은 실제로 중첩 된 사전에서주기를 감지합니다.
print dic
{'key2': {'key2.1': 'value2', 'key2.3': {...},
'key2.2': {'key1.1': 'value1'}}, 'key1': {'key1.1': 'value1'}}
"{...}" 는주기가 감지되는 곳입니다.
Moondra 가 요청 한대로 이것은주기 (DFS)를 피하는 방법입니다.
def myprint(d):
stack = list(d.items())
visited = set()
while stack:
k, v = stack.pop()
if isinstance(v, dict):
if k not in visited:
stack.extend(v.items())
else:
print("%s: %s" % (k, v))
visited.add(k)