# help with silly algorhythm

Gerson Kurz gerson.kurz at t-online.de
Fri Feb 15 05:28:03 EST 2002

```On 14 Feb 2002 21:55:27 -0800, kp87 at lycos.com (kevin parks) wrote:

>What I want to do is generate a new list of items based on
>an input list and a some criteria (list of acceptable values, for
>example).

> * list of input values =[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
> * a list of acceptable new 'partner values' = [1, 3, 7, 10]

input_list = range(12)
partner_values = [1,3,7,10]

> so we might get (in mode 1: all closest higher value)
> [ [0, 1], [1, 3], [2, 3], [3, 7], [4, 7], [5, 7], [6, 7], [7, 11]....

GetUpper = lambda i,p:filter(lambda x:x,[(y,(filter(lambda
x:x>y,p)+[None])) for y in i])

In typical Python fashion the code is obvious.

> -or (as a single new list) -
> [1, 3, 3, 7, 7, 7, 7, 11.....]

GetUpper = lambda i,p:filter(None,[(filter(lambda x:x>y,p)+[None])
for y in i])

> mode 2 (all closest value down) might be:
> [[0,10], [1, 10], [2, 1], [3, 1], [4, 3], [5,3], [6,3], [7,3], [8, 7]....

Now this is a bit tricky, what actually would be "closest down" is

[[2, 1], [3, 1], [4, 3], [5,3], [6,3], [7,3], [8, 7]....

because the first two entries - [0,10] and [1, 10] - are "wrapped"
around. (Clearly, 10 is not "closest down" to 10). So, the actual
"closest down" list can be achived by using

GetLower = lambda i,p:filter(lambda x:x,[(y,([None]+filter(lambda
x:x<y,p))[-1]) for y in i])

while the version with the wrap-around you wrote looks like this:

GetLower = lambda i,p:[(y,([p[-1]]+filter(lambda x:x<y,p))[-1]) for y
in i]

> mode 3
> [ [0, 1], [1, 10], [2, 3], [3, 1].....

A generic mix function would read

Mix = lambda f1,f2,i,p:(lambda z=zip(f1(i,p),f2(i,p)):[z[i][i%2] for i
in xrange(len(z))])()

Note the fine use of a otherwise useless lambda call for allocating
local variables. You can use Mix() like this:

print Mix(GetUpper,GetLower,input_list,partner_values)
print Mix(GetLower,GetUpper,input_list,partner_values)

```