如何在 Python 中制作树状图?

How can I make a tree diagram in Python?

这是我为对动物列表进行分类而制作的不完整树图:

horse, cow, sheep, pig, dog, cat, lion, tiger, whale, dolphin, seal, penguin, ostrich, sparrow, spider, ant, bee, wasp, termite, octopus, squid

我还没有完成添加狗、老虎、狮子等,只是因为该应用程序要求我购买一些订阅以获得更多形状,我不会那样做,但这没关系,因为我可以想象其余的部分。我的问题是;在 python 代码中,我如何制作一个程序来不断询问用户 yes/no 问题,直到它可以从列表中找出它是什么动物。我显然可以用很多 IF 语句或 OOP 和使用属性来做到这一点,但是这两种解决方案都需要我问每个问题,这将需要相当多的代码行,而且会非常难看。例如,如果用户说他们的动物是水生动物,我该怎么做,它就不会再问任何不适用于该动物的问题。例如:

如果我选择黄蜂,我对“你的动物是陆生动物吗?”的问题回答是,然后对“你的动物是哺乳动物吗?”的回答不是,然后是食肉动物并且能够fly,我该怎么做才能让程序只分支到这些问题? 基本上,我如何编写一个遵循用户输入的树形图? (我不需要任何 GUI)

您可以用 classical Node class:

定义树
class Node:
    def __init__(self, name, *children):
        self.name = name
        self.children = children

tree = Node("an animal",
    Node("aquatic",
        Node("a cephalapod",
            Node("having 8 tentacles", Node("an octopus")),
            Node("having 10 tentacles", Node("a squid"))
        ), Node("a whale",
            Node("a baleen", Node("a baleen")),
            Node("not a baleen", Node("a dolphin"))
        )
    ), Node("a land animal",
        Node("a mammal",
            Node("a bird",
                Node("able to fly", Node("a sparrow")),
                Node("not able to fly",
                    Node("a piscivore", Node("a penguin")),
                    Node("not a piscivore", Node("an ostrich"))
                )
            ), Node("not a bird",
                Node("a carnivore", Node("a lion")),
                Node("a herbivore", 
                    Node("having leather", Node("a bovine")),
                    Node("not having leather", 
                        Node("having wool", Node("a sheep")),
                        Node("not having wool", Node("a pig"))
                    )
                )
            )
        ), Node("an insect",
            Node("a carnivore",
                Node("able to fly", Node("a wasp")),
                Node("not able to fly",
                    Node("having 6 legs", Node("an ant")),
                    Node("having 8 legs", Node("a spider"))
                )
            ), Node("a herbivore", 
                Node("able to fly", Node("a bee")),
                Node("not able to fly", Node("a termite"))
            )
        )
    )
)

然后主代码可以继续问题循环:

node = tree
while node.children:
    answer = "n"
    for child in node.children[:-1]:
        print("Is it {}? (y/n)".format(child.name))
        answer = input()
        if answer.lower() == "y":
            break
    if answer.lower() != "y":
        child = node.children[-1]
    node = child
    print("It is {}".format(node.name))

虽然你的树是二叉树,但是这段代码预见到有超过2children的可能性。当对第一个 select 第一个 child 的问题回答否时,它会问第二个 child 的问题,...等等,直到只有另一个 child 保留为可能性:它不会问相应的问题,因为这是唯一剩下的选项。