help with silly algorhythm

Jeff Shannon jeff at ccvcorp.com
Fri Feb 15 20:24:24 CET 2002


Gerson Kurz wrote:

> 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).
>
> An ideal job for lambda! Lets start with the data.
>
> > * 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[1],[(y,(filter(lambda
> x:x>y,p)+[None])[0]) for y in i])
>
> In typical Python fashion the code is obvious.

Heh.  I positively cannot make heads or tails of that lambda--perhaps its a
shortcoming of mine, but extended lambdas like that make my eyes glaze and my
brain shut off....

The trick here, Kevin, is that you want to select from a list, based on a
parameter and a function.  If you can define functions that'll do what you
want, then you can use a simple list comprehension (or map() ) to process it--

inputlist = range(12)
partnerlist = [1,3,7,10]
mixed = [ (i, func(i, partnerlist)) for i in inputlist ]

This generates a pair (i, f(i) ) for each of your input values.  Now, you just
need to determine how to write f(i) for each of your "modes".  So, for
instance:

def NextHigher(key, choices):
    templist = choices[:] #make a copy
    templist.sort()    # make sure it's sorted
    for value in templist:
        if value > key:
            return value
    # If key >= max(choices), then you
    # want it to wrap around?
    return templist[0]

Similarly for next lower...

def NextLower(key, choices):
    templist = choices[:]  # make a copy
    templist.sort()    # sort it
    templist.reverse()    # then reverse it
    for value in templist:
        if value < key:
            return value
    # or, if key <= min(choices)
    return templist[0]

Given these functions, you can plug them into that list comp I gave above:

>>> higher = [ (i, NextHigher(i, partners)) for i in inputlist ]
>>> higher
[(0, 1), (1, 3), (2, 3), (3, 7), (4, 7), (5, 7), (6, 7), (7, 10),
(8, 10), (9, 10), (10, 1), (11, 1)]
>>> lower = [ (i, NextLower(i, partners)) for i in inputlist ]
>>> lower
[(0, 10), (1, 10), (2, 1), (3, 1), (4, 3), (5, 3), (6, 3),
(7, 3), (8, 7), (9, 7), (10, 7), (11, 10)]
>>>

As you can see, all you need to do is define a function that will find the
appropriate value of your partnerlist, for a given single input.  You *do* have
to test against each member of the partnerlist, until you find a match, though.

Hope this helps.  :)

Jeff Shannon
Technician/Programmer
Credit International







More information about the Python-list mailing list