Python 使用页面属性sortIndex进行树遍历
我正在基于从名为Pages的Python 使用页面属性sortIndex进行树遍历,python,google-app-engine,tree-traversal,Python,Google App Engine,Tree Traversal,我正在基于从名为Pages的db.Model中检索到的列表构建一个树结构 每个页面条目都有一个parentKey属性,即称为sortIndex的db.SelfReferenceProperty()和db.IntegerProperty() 我获取列表并调用一个方法遍历列表,并创建一个嵌套的dict作为我的树。我获取整个列表的原因是我想跳过多个查询 pages = Pages.gql('ORDER BY sortIndex').fetch(1000) build_tree(pages) 以及构建
db.Model
中检索到的列表构建一个树结构
每个页面条目都有一个parentKey属性,即称为sortIndex的db.SelfReferenceProperty()
和db.IntegerProperty()
我获取列表并调用一个方法遍历列表,并创建一个嵌套的dict作为我的树。我获取整个列表的原因是我想跳过多个查询
pages = Pages.gql('ORDER BY sortIndex').fetch(1000)
build_tree(pages)
以及构建树:
def build_tree(nodes, *args):
# create empty tree to fill
tree = {}
build_tree_recursive(tree, None, nodes, *args)
return tree
def build_tree_recursive(tree, parent, nodes, *args):
# find root children, first level nodes have no parentKey
if parent is None:
children = [n for n in nodes if n.parentKey == None]
# find children
else:
children = [n for n in nodes if n.parentKey is not None and n.parentKey.key() == parent]
# build a subtree for each child
for child in children:
# start new subtree
key = child.key()
# Use page entry key as unique dict key
tree[key] = { 'page' : child, 'children' : {}}
# call recursively to build a subtree for current node
build_tree_recursive(tree[key]['children'], key, nodes)
问题是列表get被重新排列,并且不遵循det ORDER BY。我认为这是因为当找到合适的父母时,每一页都被放在列表中。但即使是第一级(具有parentKey==None
的页面)也会以错误的顺序返回
我尝试在树[str(I)+''.'+str(key)]上使用循环计数器设置前缀,但仍然没有以正确的顺序返回
那么,问题是如何让它们按正确的顺序排列
编辑[已解决]:
请参见下面的以保留作为参数发送的列表的顺序,以构建树,我移动到了另一个角度。我改为使用列表,顺序保持不变:
def build_tree(nodes, *args):
# create empty tree to fill
t = {}
# First group all pages w/ same parent
for node in nodes:
if node.parentKey is None:
key = 'root'
else:
key = node.parentKey.key()
if not t.has_key(key):
t[key] = []
t[key].append({ 'page' : node, 'children' : []})
pageTree = t['root']
# Iterate over there
build_page_tree(pageTree, t)
return pageTree
def build_page_tree(pageTree, nodes):
#Loop over selected list
for parent, node in nodes.iteritems():
# We don't need to loop over first level node
if parent is not 'root':
# Loop over current level in page tree
for item in pageTree:
# Match keys
if item['page'].key() == parent:
# Save node as child
item['children'] = node
# Only need to loop over childs if they are present
build_page_tree(item['children'], nodes)
为了保留作为参数发送的列表的顺序以构建_树,我移动到了另一个角度。我改为使用列表,顺序保持不变:
def build_tree(nodes, *args):
# create empty tree to fill
t = {}
# First group all pages w/ same parent
for node in nodes:
if node.parentKey is None:
key = 'root'
else:
key = node.parentKey.key()
if not t.has_key(key):
t[key] = []
t[key].append({ 'page' : node, 'children' : []})
pageTree = t['root']
# Iterate over there
build_page_tree(pageTree, t)
return pageTree
def build_page_tree(pageTree, nodes):
#Loop over selected list
for parent, node in nodes.iteritems():
# We don't need to loop over first level node
if parent is not 'root':
# Loop over current level in page tree
for item in pageTree:
# Match keys
if item['page'].key() == parent:
# Save node as child
item['children'] = node
# Only need to loop over childs if they are present
build_page_tree(item['children'], nodes)
请注意,您没有在此处保存查询-每次您第一次对实体执行“n.parentkey”操作时,它都会从数据存储中获取该实体。谢谢。在过去的几个小时里,我一直在研究这个问题,并且确实注意到了这一点。有什么办法可以绕过它吗?我想我在某个地方读到过,人们可以预先捕捉到一些数据?@fredrik:如果你回答了自己的问题,而不是编辑它(甚至可能将它标记为已接受),其他人在搜索旧的、未回答的问题时,不会一次又一次地找到你的问题。@Anthon sry。修复。请注意,您没有在此处保存查询-每次您第一次对实体执行“n.parentkey”操作时,它都会从数据存储中获取实体。谢谢。在过去的几个小时里,我一直在研究这个问题,并且确实注意到了这一点。有什么办法可以绕过它吗?我想我在某个地方读到过,人们可以预先捕捉到一些数据?@fredrik:如果你回答了自己的问题,而不是编辑它(甚至可能将它标记为已接受),其他人在搜索旧的、未回答的问题时,不会一次又一次地找到你的问题。@Anthon sry。固定的。