Traversing through variable-sized lists

Peter Otten __peter__ at web.de
Wed Feb 17 20:27:41 CET 2010


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...
> 
> 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!

I tried to apply

http://en.wikipedia.org/wiki/Bresenham's_line_algorithm

on the problem:

def bresenham(xitems, yitems):
    x1 = len(xitems)
    y1 = len(yitems)

    assert y1 <= x1
    assert x1 > 0

    deltax = x1-1
    deltay = y1-1
    error = deltax // 2
    
    yitems = iter(yitems)
    y = next(yitems)

    for x in xitems:
        yield x, y
        error -= deltay
        if error < 0:
            y = next(yitems)
            error += deltax

if __name__ == "__main__":
    def make_f(i):
        def f(v):
            return "%d --> %s" % (i, v)
        return f
    functions = [make_f(i) for i in range(11)]
    values = ["b%s" % k for k in range(5)]
    for f, v in bresenham(functions, values):
        print f(v)

The implementation is derived from the code on the wikipedia page and 
untested.

Peter



More information about the Python-list mailing list