Traversing through variable-sized lists

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed Feb 17 21:54:42 CET 2010


On Feb 17, 8:24 pm, John Posner <jjpos... at optimum.net> wrote:
> 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

That's a cool trick, but maybe I wasn't specific enough. The values
series are the range of values that the frames.func() function should
use, it should not overflow, and I would want the function to use as
evenly distributed number of values as possible from the first series.
The "0000,1111" was just an example. Let me see if I can be more
specific:

values = [2, 3, 4]
frames = [obj1, obj2, obj3, obj4, obj5, obj6]

And the calls:

frames[0].func(values[0])  # func.(values[2])
frames[1].func(values[0])  # func.(values[2])
frames[2].func(values[1])  # func.(values[3])
frames[3].func(values[1])  # func.(values[3])
frames[4].func(values[2])  # func.(values[4])
frames[5].func(values[2])  # func.(values[4])


However the values list might have an uneven number of items. I would
like to make it as evenly distributed as possible, e.g.:

values = [-2, -1, 0]
frames = [obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8]

frames[0].func(values[0])  # func.(values[-2])
frames[1].func(values[0])  # func.(values[-2])
frames[2].func(values[1])  # func.(values[-2])
frames[3].func(values[1])  # func.(values[-1])
frames[4].func(values[1])  # func.(values[-1])
frames[5].func(values[2])  # func.(values[-1])
frames[6].func(values[2])  # func.(values[0])
frames[7].func(values[2])  # func.(values[0])


I'll be even more specific. I have a Minimum and Maximum value that
the user enters. The frame.func() function is a "translate" function,
it basically moves a frame in the application in one direction or
another depending on the argument value. So frame[0].func(2) would
move the frame[0] 2 pixels to the right. So what I want is the
function to create a smooth transition of all the frames from the
Minimum to the Maximum value. If minimum was 0, and maximum was 10,
I'd want the first frame moved 0 pixels (it stays in place), the last
frame to move 10 pixels, and the frames between are gradually moved
from 1 pixels to 9 pixels relative from their positions.

Perhaps I'm just overcomplicating. I'll have a look at some drawing
apps and see how they've implemented drawing straight lines under an
angle, I guess that could be called a gradual change of values.

Thanks for all the suggestions everyone, I'll have a look at the rest
shortly.



More information about the Python-list mailing list