【发布时间】:2021-12-15 19:07:37
【问题描述】:
我有一个名为 Topics 的模型,其数据如下:
| id | has_sub_topic | parent_id | subject_module_level_id | order |
|---|---|---|---|---|
| 27 | 1 | NULL | 25 | 1 |
| 31 | 1 | NULL | 25 | 2 |
| 34 | 0 | NULL | 25 | 3 |
| 28 | 0 | 27 | 25 | 1 |
| 29 | 0 | 27 | 25 | 2 |
| 40 | 1 | 27 | 25 | 3 |
| 32 | 0 | 31 | 25 | 1 |
| 33 | 0 | 31 | 25 | 2 |
| 41 | 1 | 40 | 25 | 1 |
| 43 | 0 | 40 | 25 | 2 |
| 44 | 1 | 40 | 25 | 3 |
| 42 | 0 | 41 | 25 | 1 |
| 45 | 0 | 44 | 25 | 1 |
| 47 | 1 | 44 | 25 | 2 |
| 48 | 0 | 47 | 25 | 1 |
我想先按父级排序,然后像深度优先处理一样进行子级处理,只获取没有has_sub_topic的数据。因此,数据将按如下顺序排序:https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif 并仅获取数据 4、7、8、10
之前我尝试过使用 sorted 函数,但是对于很多孩子来说效果并不好。所以,我必须使用递归函数。我使用递归的代码是这样的:
# Example data for topics
import pandas as pd
topics = pd.DataFrame({
'id': [27, 31, 34, 28, 29, 40, 32, 33, 41, 43, 44, 42, 45, 47, 48],
'has_sub_topic': [1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0],
'parent_id': [None, None, None, 27, 27, 27, 31, 31, 40, 40, 40, 41, 44, 44, 47],
'subject_module_level_id': [25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25],
'order': [1, 2, 3, 1, 2, 3, 1, 2, 1, 2, 3, 1, 1, 2, 1]
})
def topic_child_order(topic, list_topics=None):
if list_topics is None: list_topics = []
if topic.has_sub_topic:
topics = Topics.objects.filter(parent=topic).order_by('order')
for child in topics:
result = topic_child_order(child, list_topics)
else:
result = topic
list_topics.append(result)
return list_topics
topics = Topics.objects.filter(
subject_module_level_id=25,
parent=None
).order_by('order')
topics_order = []
for topic in topics:
topics_order.append(topic_child_order(topic))
结果是这样的:
[
[
<Topics: Topicsobject(28)>,
<Topics: Topicsobject(29)>,
<Topics: Topicsobject(42)>,
[
...
],
<Topics: Topicsobject(43)>,
<Topics: Topicsobject(45)>,
<Topics: Topicsobject(48)>,
[
...
],
[
...
],
[
...
],
[
...
]
],
[
<Topics: Topicsobject(32)>,
<Topics: Topicsobject(33)>,
[
...
]
],
[
<Topics: Topicsobject(34)>
]
]
排序顺序是正确的,但我不知道为什么结果有空列表。有人知道怎么修这个东西吗?或者有谁知道如何以更好的方式做到这一点,以便结果只返回一个列表而不是嵌套列表?
【问题讨论】:
-
您能用minimal reproducible example 编辑您的问题吗?特别是,您向我们展示的 15 行表完全在代码中定义?请参阅How to make good reproducible pandas examples 获取帮助。现在,如果我尝试执行你的代码,我只会得到
NameError: name 'Topics' is not defined。 -
也许你可以这样做:
import pandas as pd; topics = pd.DataFrame({'id': [27, 31, 34, ...], 'parent_id': [...], ...})。然后,阅读您的问题的人可以使用您的数据,并且更有可能想要发布答案。 -
好的,我在 pd 数据框中添加了示例数据。
标签: python recursion depth-first-search