2

我有一个分层组织,它是一棵树,如果父母赞助孩子,节点就是孩子。看来我可以用这段代码遍历树

def get_team(self, person, team):
    firstline = User.query(User.sponsor == person.key).fetch(99999999)
    if firstline:
        for person in firstline:
            team.append(person)
            newdownline = self.downline(person, team)        
    return team

使用上面我可以得到一个用户的组织只是

downline=user.get_team(user, [])

但是有没有更有效的方法,因为我必须为单个请求多次执行此操作,并且很多递归可能效率低下?或者代码会很好,因为它可以正确地遍历树?在我的第一个版本中,我使用了三个变量,我发现我可以将代码重新排列为只有两个变量,而不是这样:

def downline(self, person, team, teamlist):
    firstline = User.query(User.sponsor == person.key).fetch(99999999)
    if firstline:
        for person in firstline:
            teamlist.append(person)
            newdownline = self.downline(person, team, teamlist)        
            team.append(newdownline)
    return teamlist 

我发现 teamlist 变量并不是真正需要的,所以我删除了它。我这样做的方式是首先使用一个变量太多:

people = user.downline(user, [], [])

4

1 回答 1

1

是的,有一种更有效的方法可以做到这一点,具体取决于您的计算权衡。

您目前正在对树进行深度优先遍历,这是一种非常好的方法。您可以通过缓存结果以牺牲一些 RAM 使用为代价来提高速度,因此:

if person.id in downline_cache:
      team.append(downline_cache[person.id])
else:
      downline_cache[person.id] = results
      team.append(results)

如果树相当小,您可以预先缓存整个内容,每个线程一次。这比您正在做的事情需要更多的 RAM,但比每次您关心结果时进行深度优先遍历要快得多。很大程度上取决于您的使用模式和您存储的数据量。

如果使用缓存,则必须确保有某种方法来处理底层数据的变化,或者使用超时和“最终正确”的类型保证,或者跟踪必须何时以及如何擦除缓存,或缓存。

于 2012-03-13T17:35:20.980 回答