如何在 python 中从字典中打印树
How to print tree from dictionary in python
我正在尝试在 python 中实现 ldd 类应用程序。但是,我正在努力将数据表示为树状结构。 linux 库依赖于其他一些库,所以我的任务是跟踪依赖列表,直到找不到依赖为止。
我在下面显示的字典中有数据,
{lib_A: [lib_1, lib_2, lib_3, lib_4], lib_1: [lib_x, lib_y, lib_z], lib_x: [lib_i], lib_y: [lib_p], lib_2: [lib_a, lib_b], lib_a: [lib_11]......}
其中 lib_1, lib_2, lib_3,而 lib_4 取决于 lib_A。那么lib_x,lib_y,还有lib_z在 lib_1 等等。该列表一直持续到找不到依赖项为止。如果我在 for 循环中打印数据,输出如下所示,
for lib, dep_lib in dependency_dict.items():
print(lib, dep_lib)
lib_A [lib_1, lib_2, lib_3, lib_4]
lib_1 [lib_x, lib_y, lib_z]
lib_x [lib_i]
lib_y [lib_p]
lib_2 [lib_a, lib_b]
lib_a [lib_11]
...
..
我想将上述数据表示为树状结构,如下所示。
lib_A <= lib_1
<= lib_x
<= lib_i
<= lib_y
<= lib_p
<= lib_z
<= lib_2
<= lib_a
<= lib_11
<= lib_b
<= lib_3
<= lib_4
在处理基于树的结构时,通常很自然地使用递归函数来处理它。为了产生你想要的输出,我会写这样的东西:
def process_lib(data, lib, padding=0):
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
for child in data.get(lib, []): # base case: lib is not in the dict
process_lib(data, child, padding + 3) # recursive case
这并没有完全复制您的示例的第一行,因为我们将 lib_A
放在单独的一行,而 lib_1
放在下一行。您可以为 padding == 0
案例添加更多特殊案例逻辑,并弄清楚如何让第一个 child 直接跟随它,但希望这个输出足够好:
lib_A
<= lib_1
<= lib_x
<= lib_i
<= lib_y
<= lib_p
<= lib_z
<= lib_2
<= lib_a
<= lib_11
<= lib_b
<= lib_3
<= lib_4
此代码可能只适用于简单的树。如果您的真实数据是一个更复杂的图形,在依赖层次结构中的多个点显示相同的库,那么您需要更复杂的东西。您需要跟踪已经看到哪些节点,或者根本不再打印它们,或者打印它们但不打印它们的依赖关系。这是执行后者的实现:
def process_lib(data, lib, padding=0, seen=None):
if seen is None:
seen = set()
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
if lib in seen:
print(" "*(padding+3), "<= ...") # alternate base case
else:
seen.add(lib)
for child in data.get(lib, []):
process_lib(data, child, padding + 3, seen)
如果您根本不想重复,请使用:
def process_lib(data, lib, padding=0, seen=None):
if seen is None:
seen = set()
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
seen.add(lib)
for child in data.get(lib, []):
if child not in seen:
process_lib(data, child, padding + 3, seen)
我正在尝试在 python 中实现 ldd 类应用程序。但是,我正在努力将数据表示为树状结构。 linux 库依赖于其他一些库,所以我的任务是跟踪依赖列表,直到找不到依赖为止。 我在下面显示的字典中有数据,
{lib_A: [lib_1, lib_2, lib_3, lib_4], lib_1: [lib_x, lib_y, lib_z], lib_x: [lib_i], lib_y: [lib_p], lib_2: [lib_a, lib_b], lib_a: [lib_11]......}
其中 lib_1, lib_2, lib_3,而 lib_4 取决于 lib_A。那么lib_x,lib_y,还有lib_z在 lib_1 等等。该列表一直持续到找不到依赖项为止。如果我在 for 循环中打印数据,输出如下所示,
for lib, dep_lib in dependency_dict.items():
print(lib, dep_lib)
lib_A [lib_1, lib_2, lib_3, lib_4]
lib_1 [lib_x, lib_y, lib_z]
lib_x [lib_i]
lib_y [lib_p]
lib_2 [lib_a, lib_b]
lib_a [lib_11]
...
..
我想将上述数据表示为树状结构,如下所示。
lib_A <= lib_1
<= lib_x
<= lib_i
<= lib_y
<= lib_p
<= lib_z
<= lib_2
<= lib_a
<= lib_11
<= lib_b
<= lib_3
<= lib_4
在处理基于树的结构时,通常很自然地使用递归函数来处理它。为了产生你想要的输出,我会写这样的东西:
def process_lib(data, lib, padding=0):
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
for child in data.get(lib, []): # base case: lib is not in the dict
process_lib(data, child, padding + 3) # recursive case
这并没有完全复制您的示例的第一行,因为我们将 lib_A
放在单独的一行,而 lib_1
放在下一行。您可以为 padding == 0
案例添加更多特殊案例逻辑,并弄清楚如何让第一个 child 直接跟随它,但希望这个输出足够好:
lib_A
<= lib_1
<= lib_x
<= lib_i
<= lib_y
<= lib_p
<= lib_z
<= lib_2
<= lib_a
<= lib_11
<= lib_b
<= lib_3
<= lib_4
此代码可能只适用于简单的树。如果您的真实数据是一个更复杂的图形,在依赖层次结构中的多个点显示相同的库,那么您需要更复杂的东西。您需要跟踪已经看到哪些节点,或者根本不再打印它们,或者打印它们但不打印它们的依赖关系。这是执行后者的实现:
def process_lib(data, lib, padding=0, seen=None):
if seen is None:
seen = set()
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
if lib in seen:
print(" "*(padding+3), "<= ...") # alternate base case
else:
seen.add(lib)
for child in data.get(lib, []):
process_lib(data, child, padding + 3, seen)
如果您根本不想重复,请使用:
def process_lib(data, lib, padding=0, seen=None):
if seen is None:
seen = set()
if padding == 0:
print(lib)
else:
print(" "*padding, "<=", lib)
seen.add(lib)
for child in data.get(lib, []):
if child not in seen:
process_lib(data, child, padding + 3, seen)