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 = []