Traversing through variable-sized lists
John Posner
jjposner at optimum.net
Wed Feb 17 14:24:52 EST 2010
On 2/17/2010 1:10 PM, Andrej Mitrovic wrote:
> Hi,
>
> I couldn't figure out a better description for the Subject line, but
> anyway, I have the following:
>
> _num_frames = 32
> _frames = range(0, _num_frames) # This is a list of actual objects,
> I'm just pseudocoding here.
> _values = [0, 1, 2, 3, 4]
>
> I want to call a function of _frames for each frame with a _values
> argument, but in a way to "spread out" the actual values.
>
> I would want something similar to the following to be called:
>
> _frames[0].func(_values[0])
> _frames[1].func(_values[0])
> _frames[2].func(_values[0])
> _frames[3].func(_values[0])
> _frames[4].func(_values[1])
> _frames[5].func(_values[1])
> _frames[6].func(_values[1])
> _frames[7].func(_values[1])
> _frames[8].func(_values[2])
> ...etc...
The lines above show that you are using two different series of index
values. Each function call (more properly, "method call") has the form:
frames[INDEX_FROM_FIRST_SERIES].func(INDEX_FROM_SECOND_SERIES)
(I've dropped the underscores in the names, for simplicity.) You're
getting hung up trying to keep the two series of index values in sync.
But you don't really need to. More below ...
>
> Both the _values list and _frames list can be of variable and uneven
> size, which is what is giving me the problems. I'm using Python 2.6.
>
> I've tried the following workaround, but it often gives me inaccurate
> results (due to integer division), so I had to add a safety check:
>
> num_frames = 32
> values = [0, 1, 2, 3, 4]
> offset_step = num_frames / len(values)
> for index in xrange(0, num_frames):
> offset = index / offset_step
> if offset> offset_values[-1]:
> offset = offset_values[-1]
> frames[index].func(values[offset])
>
> There has to be a better way to do this. I'd appreciate any help.
> Cheers!
As you've shown above, a "for" loop takes care of the first series of
index values:
for index in xrange(num_frames): # "0" arg unnecessary
frames[index].func(INDEX_FROM_SECOND_SERIES)
The second series of index values needs to look like this:
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3 ...
The trick is not to worry about matching the second series to the first
series. Instead, create an "infinite" second series using a Python
generator, and use as many of its values as you need. Don't worry about
the unused values, because the series isn't *really* infinite. :-)
Here's an easy way to create the generator
import itertools
second_series_gen = (i/4 for i in itertools.count())
Now, every time you need another number from this series, use its next()
method. So the above code becomes:
for index in xrange(num_frames):
frames[index].func(second_series_gen.next())
-John
More information about the Python-list
mailing list