serial iteration over several lists

M

Martin DeMello

Within Blender, I have access to a list of Objects, each Object
containing a list of Meshes and each Mesh a list of Faces. I'd like to
implement a face iterator, with both a next() and a prev() method, such
that if I go off the end of a face list, it goes to the first face in
the next mesh, similarly for going off the end of the last mesh in an
object, and similarly for the prev() iterator.

In other words, I want to simulate appending all the faces into one long
list, but without the overhead of actually creating the list. I can
think of several ways to do it, but they all feel like solutions
'translated' from some other language - is there a nice pythonic way to
do this?

martin
 
B

Brandon

How about this:
.... return itertools.chain(*meshes)
....
.... ["face1", "face2", "face3"],
.... ["face4", "face5", "face6"],
.... ["face7", "face8", "face9"],
.... ["face10", "face11", "face12", "face13"],
.... ]['face1', 'face2', 'face3', 'face4', 'face5', 'face6', 'face7',
'face8', 'face9', 'face10', 'face11', 'face12', 'face13']
 
M

Martin DeMello

Brandon said:
How about this:

... return itertools.chain(*meshes)
[...]

Thanks - that looks like an excellent starting point. Has there been any
work done on bidirectional iterators?

martin
 
J

Jeffrey Froman

Martin said:
Thanks - that looks like an excellent starting point. Has there been any
work done on bidirectional iterators?

You could emulate one by maintaining a counter for the current index into
the imaginary flattened list, and iterating up to that index with each
prev() call and just past it with each next(). This of course requires that
you basically start from the beginning of your nested list each time
though, and I'm not sure if it would be more or less efficient than
indexing into a pre-flattened list in memory.

One more suggestion -- if you use a recursive generator for your iteration,
you can then use it with a list nested to arbitrary depth, something like:

#############################################

def deep_iter(nested_list):
for x in nested_list:
if isinstance(x, list):
for n in deep_iter(x):
yield n
else:
yield x

#############################################


Jeffrey
 
M

Martin DeMello

Jeffrey Froman said:
You could emulate one by maintaining a counter for the current index into
the imaginary flattened list, and iterating up to that index with each
prev() call and just past it with each next(). This of course requires that
you basically start from the beginning of your nested list each time
though, and I'm not sure if it would be more or less efficient than
indexing into a pre-flattened list in memory.

I ended up just maintaining a few list indexes, and writing code to wrap
them around properly - turned out to be the simplest way since
bidirectionality was more important than iterator-like support.
One more suggestion -- if you use a recursive generator for your iteration,
you can then use it with a list nested to arbitrary depth, something like:

#############################################

def deep_iter(nested_list):
for x in nested_list:
if isinstance(x, list):
for n in deep_iter(x):
yield n
else:
yield x

#############################################

I thought of that, but again it proved nigh impossible to backtrack
cleanly over. The other idea I had was to maintain two iterators, one
going forwards and one going backwards, and reinitialize them as needed.
For example, if I wanted to do that over the list [1,2,3,4,5,6,7,8,9]
I'd set forward to 1 and reverse to 9, then iterate forward as long as
next was called, then when prev was called, reinitialize reverse to
wherever the index had reached and call its next method.

martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top