Python 将pymysql注释对象递归转换为树

Python 将pymysql注释对象递归转换为树,python,algorithm,sqlite,recursion,pymysql,Python,Algorithm,Sqlite,Recursion,Pymysql,我正在尝试创建一个评论系统,作为业余爱好项目的一部分,但我不知道如何在从数据库中获取评论对象后对其进行递归排序。我使用的关系数据库具有以下数据模型: class Comment(Base): __tablename__ = 'comments' id = Column(Integer, primary_key=True) comment = Column(String(), nullable=False) user_id = Column(Integer, For

我正在尝试创建一个评论系统,作为业余爱好项目的一部分,但我不知道如何在从数据库中获取评论对象后对其进行递归排序。我使用的关系数据库具有以下数据模型:

class Comment(Base):
    __tablename__ = 'comments'
    id = Column(Integer, primary_key=True)
    comment = Column(String(), nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    post_id = Column(Integer, ForeignKey('posts.id'), nullable=False)
    parent_id = Column(Integer, ForeignKey('comments.id'), nullable=False)
一旦我从数据库中获得了数据,我需要在树中对这些对象进行排序。例如,输入示例可以是:

comments = [
            <models.Comment object at 0x104d80358>,
            <models.Comment object at 0x104d803c8>,
            <models.Comment object at 0x104d80470>, 
            <models.Comment object at 0x104d80518>,
            <models.Comment object at 0x104d805c0>,
            <models.Comment object at 0x104d80668>
           ]
注释=[
,
,
, 
,
,
]
预期结果可能是:

comment_dict = {1: {'comment':<Comment.object>, 'children':[]},
               {2: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]},
               {3: {'comment':<Comment.object>, 'children':[]},
               {4: {'comment':<Comment.object>, 'children':[<Comment.object>, ...]} ...
comment_dict={1:{'comment':,'children':[]},
{2:{'comment':,'children':[,…]},
{3:{'comment':,'children':[]},
{4:{'comment':,'children':[,…]}。。。
任何评论对象都可以有无限多的子对象。几乎就像reddit和其他类似社交媒体网站上使用的评论系统一样。 对于渲染,我正在使用flask和Jinja,并且可能会执行类似于我在文档中找到的操作:

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
    {%-用于站点地图中的项目递归%}
  • {%-if item.children-%}
      {{loop(item.children)}
    {%-endif%}
  • {%-endfor%}


在进行此操作之前,我不知道如何对数据进行排序。

非常简单的方法是:

def comments_to_dict(comments):
    result = {}
    for comment in comments:
        result[comment.id] = {
            'comment': comment,
            'children': []
        }
    for comment in comments:
        result[comment.parent_id]['children'].append(comment)
    return result
因此,首先用
子元素
将根元素填充为空,然后在第二遍填充子元素。只需对
注释
进行一次遍历,就可以进一步改进这一点:

def comments_to_dict(comments):
    result = {}
    for comment in comments:
        if comment.id in result:
            result[comment.id]['comment'] = comment
        else:
            result[comment.id] = {
                'comment': comment,
                'children': []
            }

        if comment.parent_id in result:
            result[comment.parent_id]['children'].append(comment)
        else:
            result[comment.parent_id] = {
                'children': [comment]
            }
    return result
这里的解决方案与您向我们展示的预期输出相匹配


如果你想要一棵真正的树,那么试试这个

def comments_to_dict(comments):
    index = {}
    for comment in comments:
        index[comment.id] = {
            'comment': comment,
            'children': []
        }
    for obj in index.itervalues():
        pid = obj['comment'].parent_id
        index[pid]['children'].append(obj)
    return index

但是这会允许一个无限深的评论树吗?@Marius arbitative deep tree可以在两个过程中实现。我已经更新了答案。这可以像以前一样在一个过程中实现。我将把它留给你作为一个练习。