在递归函数中保持计数
这是第二个关于递归的问题。我需要在递归函数中给值分配唯一的ID。
可以想象一个文件夹结构,每个文件夹可以包含物品或其他文件夹。但是每个文件夹和物品都需要一个独特的“ID”。
我想,由于在Python的递归函数中不能使用全局变量,所以我决定在每次调用时增加ID的值。但我错得离谱。想象一下以下情况。
1 - 文件夹
2 - 文件夹
3 - 物品
4 - 物品
2 - 文件夹
由于递归的工作方式,ID会被分配两次,而且没有办法检查。那我该怎么做呢?(我在使用Python。每当我有一个变量'uniqueid'并试图增加它时,我会遇到这个错误:
局部变量 'uniqueid' 在赋值前被引用
)我的代码:make_link_item只是返回一个字符串。
def build_xml(node,depth,itemid):
#if 'Children' in node:
#print colleges
depth += 1
for child in node['Children']:
itemid += 1
print (" " * (depth - 1)) + "<item identifier=\"%s\" identifierref=\"%s\">" % (("itm" + ("%05d" % itemid)),("res" + ("%05d" % itemid)))
print (" " * depth) + "<title>%s</title>" % child['Name'].encode('utf-8')
build_xml(child,depth,itemid)
print (" " * (depth - 1)) + "</item>"
lectures = getlectures(node['Id'])
if lectures:
build_lectures(lectures,itemid,itemid)
def build_lectures(lectures,itemid,parentid):
for x in range(len(lectures)):
itemid += 1
if x % 2 == 0:
print "<item identifier=\"%s\" identifierref=\"%s\">" % (("itm" + ("%05d" % itemid)),("res" + ("%05d" % itemid)))
print "<title>" + lectures[x].encode('utf-8') + "</title>"
print "</item>"
else:
make_link_item(lectures[x-1].encode('utf-8'),lectures[x].encode('utf-8'),itemid,parentid)
谢谢,
Mats
3 个回答
0
你可以让每次调用 build_xml 的时候返回它所有子节点中最大的标识符。然后你可以把下一个节点的标识符设置为那个最大值加 1。就像这样:
def build_xml(node,depth,itemid):
depth += 1
for child in node['Children']:
itemid += 1
print (" " * (depth - 1)) + "<item identifier=\"%s\" identifierref=\"%s\">" % (("itm" + ("%05d" % itemid)),("res" + ("%05d" % itemid)))
print (" " * depth) + "<title>%s</title>" % child['Name'].encode('utf-8')
itemid = build_xml(child,depth,itemid)
print (" " * (depth - 1)) + "</item>"
lectures = getlectures(node['Id'])
if lectures:
build_lectures(lectures,itemid,itemid)
return itemid
0
我通过使用collections里的Counter()类解决了这个问题。
出于某种明显的原因:
counter = Counter()
这段代码运行得很好,我可以这样增加它的值。
counter['id'] += 1
即使在我的递归循环中也是如此。我不知道具体原因,但我觉得这和引用传递和数值传递有关。
1
我希望我没有漏掉问题。
你可以创建一个叫做 class Builder
的类,这个类的作用是用来构建 XML 树状结构。你的类里面有一个成员变量 increment
,每当你遇到一个新的项目时,就把它加一。这样的话,就不会有两个相同的 ID 了。
class Builder:
def __init__(self):
self.increment = 0
#other methods you need