Python 用for循环追加正在迭代的列表

Python 用for循环追加正在迭代的列表,python,for-loop,Python,For Loop,有人提到下面的函数(在本例中是一个方法)不好,因为它在遍历列表时修改列表。为什么会这样,因为它完全符合我的意图。事实上我对它很满意。。。有没有更好的写作方法 数据结构、功能和输出如下: nodes = { ('foo','bar',1), ('foo','baz',1), ('baz','gad',0), ('boo','moo',1), ('goo','loo',0), ('bar','far'

有人提到下面的函数(在本例中是一个方法)不好,因为它在遍历列表时修改列表。为什么会这样,因为它完全符合我的意图。事实上我对它很满意。。。有没有更好的写作方法

数据结构、功能和输出如下:

nodes = { ('foo','bar',1),
          ('foo','baz',1),
          ('baz','gad',0),
          ('boo','moo',1),
          ('goo','loo',0),
          ('bar','far',1),
          ('far','aaa',0) }

class Graph(dict):

    def __missing__(self, key):
        self[key] = set()
        return self[key]

    def add_node_pairs(self, node_pairs):
        for pair in node_pairs:
            nodeA, nodeB, weight = pair
            self[nodeA].add((weight, nodeB))
            self[nodeB].add((weight, nodeA)) 

    def find_paths(self, keys):      
        paths = [(key,) for key in keys if key in self]
        for path in paths:
            *oldkeys, key = path
            for weight, next_key in self[key]:
                if next_key not in oldkeys:
                    paths.append( path + (weight,next_key) )

        paths.sort()
        return paths

graph = Graph()
graph.add_node_pairs(nodes)
print(graph)
print( graph.find_paths(['foo']))

图表:

{ 'goo': {(0, 'loo')}, 
  'foo': {(1, 'bar'), (1, 'baz')}, 
  'aaa': {(0, 'far')}, 
  'far': {(1, 'bar'), (0, 'aaa')}, 
  'baz': {(0, 'gad'), (1, 'foo')}, 
  'loo': {(0, 'goo')}, 
  'moo': {(1, 'boo')}, 
  'boo': {(1, 'moo')}, 
  'bar': {(1, 'far'), (1, 'foo')}, 
  'gad': {(0, 'baz')} }
查找路径(“foo”):


考虑以下三个例子:

l = [1]
for x in l:
    if x < 10 # avoid infinite loop
         l.append(x+1)
    print x
此函数的输出将与预期输出1,2,3,4,5不同:1,3,5。 因此,在当前迭代器之前删除项也是不好的


为了简化事情,我们只需假设在循环时应避免更改列表的内容,除非您确切知道自己在做什么以及它可能对输出造成什么影响。

考虑以下三个示例:

l = [1]
for x in l:
    if x < 10 # avoid infinite loop
         l.append(x+1)
    print x
此函数的输出将与预期输出1,2,3,4,5不同:1,3,5。 因此,在当前迭代器之前删除项也是不好的


为了简化事情,我们只需要说,在循环时应该避免更改列表的内容,除非您确切地知道自己在做什么,以及它可能对输出造成什么影响。

在您正在迭代的列表中追加内容是安全的。如果您的代码审阅者不接受这一点,或者您仍然觉得它粘糊糊的,您可以使用两阶段方法:

paths = [blah blah]
next_paths = []
while paths:
    for path in paths:
        if something_or_other:
            next_paths.append(blah)
    paths = next_paths
    next_paths = []

添加到您正在迭代的列表是安全的。如果您的代码审阅者不接受这一点,或者您仍然觉得它粘糊糊的,您可以使用两阶段方法:

paths = [blah blah]
next_paths = []
while paths:
    for path in paths:
        if something_or_other:
            next_paths.append(blah)
    paths = next_paths
    next_paths = []

我认为您的第一个示例将无限循环,您每次都附加1,并测试它是否小于10。如果它是
l.append(x+1)
work@ThemanontheClaphamomnibus这甚至不是正确的代码,缺少了
,但它让想法得以实现。然而,OP的代码为什么不会进入无限循环?@jadkik94,这是因为只有当for循环迭代的元组的最后一个值在字典中时,列表才会被扩展。如果没有,则不添加任何内容。由于字典是有限的,并且值不允许在一个元组中出现两次,因此不能使用for循环infinite@ThemanontheClaphamomnibus这是有道理的,所以你确实有一个很好的理由去做你正在做的事情:)嗯,我想是的。。。但当人们说这是“坏习惯”时,我会尽力去听。。。只要pythonistas不开始用我做巫毒娃娃。。我很高兴!我认为您的第一个示例将无限循环,您每次都附加1,并测试它是否小于10。如果它是
l.append(x+1)
work@ThemanontheClaphamomnibus这甚至不是正确的代码,缺少了
,但它让想法得以实现。然而,OP的代码为什么不会进入无限循环?@jadkik94,这是因为只有当for循环迭代的元组的最后一个值在字典中时,列表才会被扩展。如果没有,则不添加任何内容。由于字典是有限的,并且值不允许在一个元组中出现两次,因此不能使用for循环infinite@ThemanontheClaphamomnibus这是有道理的,所以你确实有一个很好的理由去做你正在做的事情:)嗯,我想是的。。。但当人们说这是“坏习惯”时,我会尽力去听。。。只要pythonistas不开始用我做巫毒娃娃。。我很高兴!
paths = [blah blah]
next_paths = []
while paths:
    for path in paths:
        if something_or_other:
            next_paths.append(blah)
    paths = next_paths
    next_paths = []