Có những vấn đề tiềm ẩn nếu bạn viết triển khai đệ quy của riêng mình hoặc tương đương lặp lại với ngăn xếp. Xem ví dụ này:
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
Theo nghĩa thông thường, từ điển lồng nhau sẽ là một cây n-nary giống như cấu trúc dữ liệu. Nhưng định nghĩa này không loại trừ khả năng có một cạnh chéo hoặc thậm chí là một cạnh sau (do đó không còn là cây nữa). Ví dụ, ở đây key2.2 giữ từ điển từ key1 , key2.3 trỏ đến toàn bộ từ điển (cạnh sau / chu kỳ). Khi có một cạnh quay lại (chu kỳ), ngăn xếp / đệ quy sẽ chạy vô hạn.
root<-------back edge
/ \ |
_key1 __key2__ |
/ / \ \ |
|->key1.1 key2.1 key2.2 key2.3
| / | |
| value1 value2 |
| |
cross edge----------|
Nếu bạn in từ điển này với sự triển khai này từ Scharron
def myprint(d):
for k, v in d.items():
if isinstance(v, dict):
myprint(v)
else:
print "{0} : {1}".format(k, v)
Bạn sẽ thấy lỗi này:
RuntimeError: maximum recursion depth exceeded while calling a Python object
Tương tự với việc triển khai từ người gửi .
Tương tự, bạn nhận được một vòng lặp vô hạn với việc triển khai này từ 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))
Tuy nhiên, Python thực sự phát hiện các chu trình trong từ điển lồng nhau:
print dic
{'key2': {'key2.1': 'value2', 'key2.3': {...},
'key2.2': {'key1.1': 'value1'}}, 'key1': {'key1.1': 'value1'}}
"{...}" là nơi phát hiện một chu kỳ.
Theo yêu cầu của Moondra, đây là một cách để tránh chu kỳ (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)