修改我正在循环的列表是不对的,如果这就是我想要的那样?

时间:2017-07-26 16:02:58

标签: python

我已经多次读过,循环遍历你在循环体中修改的列表是个坏主意,并且有充分的理由。在

的情况下,这也适用
  1. 我只是在列表中添加新元素,而不是删除项目;
  2. 这是我真正想要的行为吗?
  3. 这是我的代码:"搜索"方法用于收集具有目标标签的所有节点的有效负载,而不是具有目标标签的节点的后代。

    class Tree:
        def __init__(self, label, payload, children):
            self.label = label # string
            self.payload = payload # some kind of data carried by the node
            self.children = children # list of Trees
    
        def search(self, target):
            nodes = [self]
            result = []
            for node in nodes:
                if node.label == target:
                    result.append(node.payload)
                else:
                    nodes += node.children
            return result
    

    这个例子有什么问题吗?我当然可以将它转换为递归函数或while循环,但这似乎是最优雅的方式(并且我不会遇到python的递归深度限制)。

2 个答案:

答案 0 :(得分:1)

我从逻辑角度看不到任何巨大的地雷,所以我觉得你没事。

从算法/性能角度来看,您(可能)最好使用队列。队列而不是列表的优点是:

  • 随着队列的增长,您不会支付调整费用
  • 您不需要对树中的每个节点进行额外的引用

Python在collections中提供了一个可行的队列,我建议您使用:

def search(self, target):
    queue = collections.deque([self])
    result = []
    while queue:
        node = queue.popleft()
        if node.label == target:
            result.append(node.payload)
        else:
            queue.extend(node.children)
    return result

我们只使用了一行额外的代码,并且我们有一些更好的数据结构,所以我推荐这种方法。 (另外,如果将search更改为生成器函数,则可以为行中的净减少保存2行代码)

答案 1 :(得分:0)

Python documentation说:

  

内部计数器用于跟踪下一个使用的项目,并在每次迭代时递增。当该计数器达到序列的长度时,循环终止。

您的代码似乎是安全的。