在递归函数中保持计数

1 投票
3 回答
1318 浏览
提问于 2025-04-17 14:22

这是第二个关于递归的问题。我需要在递归函数中给值分配唯一的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

撰写回答