From: Roald de Vries on
Hi all,


I have a list that I'm iterating over, and during the iteration items
are appended. Moreover, it is iterated over in two nested loops. If
the inner loop comes to the end, I want the outer loop to append an
item. Is there a way to do this? Because once an iterator has raised a
StopIteration, it can not go to a next item anymore.

Aside question: is there a rationale for the current behavior? To me
it seems more natural to continue iteration after appending new items.


I want to use it for a graph walk.

nodes is a list of all nodes,
edges is an on the fly constructed list of edges in the order of
visiting,
initial_nodes is a list of (root) nodes

edges = []
edge_it = iter(edges)
for node in initial_nodes:
edges += node.leaving_edges
try:
while True:
edge = edge_it.next()
edges += edge.head.leaving_edges
except StopIteration:
pass


Thanks in advance, cheers, Roald
From: MRAB on
Roald de Vries wrote:
> Hi all,
>
>
> I have a list that I'm iterating over, and during the iteration items
> are appended. Moreover, it is iterated over in two nested loops. If the
> inner loop comes to the end, I want the outer loop to append an item. Is
> there a way to do this? Because once an iterator has raised a
> StopIteration, it can not go to a next item anymore.
>
> Aside question: is there a rationale for the current behavior? To me it
> seems more natural to continue iteration after appending new items.
>
>
> I want to use it for a graph walk.
>
> nodes is a list of all nodes,
> edges is an on the fly constructed list of edges in the order of visiting,
> initial_nodes is a list of (root) nodes
>
> edges = []
> edge_it = iter(edges)
> for node in initial_nodes:
> edges += node.leaving_edges
> try:
> while True:
> edge = edge_it.next()
> edges += edge.head.leaving_edges
> except StopIteration:
> pass
>
>
> Thanks in advance, cheers, Roald

You could add the new edges to another list:

edges = []
pending_edges = []
for node in initial_nodes:
pending_edges += node.leaving_edges
while pending_edges:
new_edges = []
for edge in pending_edges:
new_edges += edge.head.leaving_edges
edges += pending_edges
pending_edges = new_edges

or use indexing:

edges = []
for node in initial_nodes:
edges += node.leaving_edges
index = 0
while index < len(edges):
edges += edges[index].head.leaving_edges
index += 1