0

我有具有属性的评论列表:(pk主键),parent_pk(父键的主键)和其他...我想在嵌套方面显示它们 - 如果评论有孩子,显示评论,然后是缩进更多的孩子. 当评论与其他评论pk相同时,评论是其他评论的子评论parent_pk

我最初将在我的 Django 博客中实现它,但首先我想学习如何做。这就是为什么为了简单起见,我创建了 CLI 应用程序。我知道那里有现成的解决方案,但我想学会自己做。:)

这是我现在的代码:

class Comment(object):
    def __init__(self, pk, parent_pk, content):
        self.pk = pk
        self.parent_pk = parent_pk
        self.content = content

    def has_children(self, comments):
        for comment in comments:
            if self.pk == comment.parent_pk:
                return True
        return False

    def get_children(self, comments):
        children = []
        for comment in comments:
            if self.pk == comment.parent_pk:
                children.append(comment)
        return children


def print_nested(comments, level=0):
    def to_whitespaces(level):
        if level == 0:
            return ""
        else:
            return " " * (level * 2)

    for comment in comments:
        print to_whitespaces(level) + comment.content
        if comment.has_children(comments):
            print_nested(comment.get_children(comments), level + 1)
            comments.pop(0)

comments = [
    Comment(1, None, "foo"),
    Comment(2, 1, "foo bar"),
    Comment(3, None, "spam"),
    Comment(4, 3, "spam cheese"),
    Comment(5, 4, "spam cheese monty"),
    Comment(6, None, "muse"),
]

print_nested(comments)

这是 Sprunge.us 上的内容(带语法)。

预期结果:

foo
  foo bar
spam
  spam cheese
    spam cheese monty
muse

实际结果:

foo
  foo bar
spam
  spam cheese
spam cheese monty
muse

如您所见,spam cheese monty它根本没有缩进。任何想法为什么会这样?你将如何实施它?谢谢!

4

3 回答 3

1

当您递归调用时print_nested,您只能使用当前元素的子元素调用它。

所以文你呼唤print_nested的孩子spam,你得到的只是spam cheese

这意味着当您调用get_childrenon时,您传递它spam cheese的列表中没有元素,因此不会缩进,因为它仅作为最外层调用的成员遇到。commentsspam cheese montyprint_nested

如果要保持脚本的当前结构,则需要进行get_children递归,因此它会无限查找子项的子项。

更好的方法是从评论中构建一个真正的树,您可以在其中实际查找父评论而无需进行列表遍历。

一种适用于您的示例的简单方法,可以轻松转换为使用树而不是列表:

class Comment(object):
    def __init__(self, pk, parent_pk, content):
        self.pk = pk
        self.parent_pk = parent_pk
        self.content = content

    def depth(self):
        depth = 0
        comment = self
        # this is just a recursive lookup converted to iterative
        while comment.parent_pk:
            # replace the array indexing with traversing up a tree
            comment = comments[comment.parent_pk - 1]
            depth += 1
        return depth

def print_nested(comments):
    for comment in comments:
        print comment.depth() * 2 * " " + comment.content

comments = [
    Comment(1, None, "foo"),
    Comment(2, 1, "foo bar"),
    Comment(3, None, "spam"),
    Comment(4, 3, "spam cheese"),
    Comment(5, 4, "spam cheese monty"),
    Comment(6, None, "muse"),
]

print_nested(comments)
于 2012-10-14T18:25:34.720 回答
1

你只需要一个递归函数来检查孩子并打印它们:

class Comment(object):
    def __init__(self, pk, parent_pk, content):
        self.pk = pk
        self.parent_pk = parent_pk
        self.content = content



def print_nested(comments,pk=None,level=0):
    for comment in comments:
        if comment.parent_pk==pk:
            print ' ' * (level * 2), comment.content
            print_nested(comments,comment.pk,level+1)

comments = [
    Comment(101, None, "foo"),
    Comment(201, 101, "foo bar"),
    Comment(301, None, "spam"),
    Comment(415, 301, "spam cheese"),
    Comment(505, 415, "spam cheese monty"),
    Comment(622, None, "muse"),
]

print_nested(comments)
于 2012-10-14T18:53:04.710 回答
0

在显示 Comment(4, 3, "spam cheese") 后,它作为 Comment(3, None, "spam") 的子级发生,您会从评论中弹出它。因此,当您处理 Comment(5, 4, "spam cheese monty") 时,缺少父“pk”,因此结果显示为 root

于 2012-10-14T18:10:32.300 回答