views:

54

answers:

1

All,

I have confuse below may need your help

suppose I have a row based variable length data matrix

93  77  96  85
50  69  54  16
39  91  59  38
64  30  18  50
43  9   74  94
44  87  95  89
... 

I want to generate result data via above source with different generating algorithms while the different range selection algorithms, take below code for example

lsrc = [# above data]

def rangesel_001(lsrc):
    tmp = []
    for i in len(lsrc):
       if i % 2 = 0:
          tmp.append(lsrc[i])
    return tmp

def algo_001(lsrc):
    tmp = []
        for i in len(lsrc):
            tmp.append([x+1 for x in lsrc[i]]) 
    return tmp

So the data I want is:

dscl = algo_001(rangesel_001(lsrc))

Here comes is my questions:

1. suppose I have an extendable "rangesel" set and the "algo" is also extendable looks like this

rangesel_001()     algo_001()
rangesel_002()     algo_002()
rangesel_003()     algo_003()
…                    ...

I want to mix them, then invoke them in-a-go to get all the result what I want

rangesel_001 + algo_001
rangesel_001 + algo_002
rangesel_001 + algo_003

rangesel_002 + algo_001
rangesel_002 + algo_002
rangesel_002 + algo_003
...

is there a way easy to manager those function names then combine them to execute?

2. you may noticed the different part in “rangesel”s and “algo”s algorithm is snippet here:

if i % 2 = 0:
 and
[x+1 for x in lsrc[i]]

It there a way to exact those common part out from function definitions and I can just give somekind a list:

if i % 2 = 0   rangesel_001
if i % 3 = 0   rangesel_002
if i % 4 = 0   rangesel_003
 and
[x+1 for x in lsrc[i]] algo_001
[x/2 for x in lsrc[i]] algo_002

then I can get all the “rangeset” functions and "algo" sets?

3. maybe later I need this:

dscl = algo_001(rangesel_001(                             \
                             algo_002(rangesel_002(lsrc)) \  
                            ))

so, is there a painfulless way I can chain those "rangesel_002 + algo_001" combinations? for example: suppose I already have the full combinations

rangesel_001 + algo_001
rangesel_001 + algo_002
rangesel_001 + algo_003

rangesel_002 + algo_001
rangesel_002 + algo_002
rangesel_002 + algo_003

now I want to pick random 3 to chain them and invoke to get result list?

dscl = random_pick(3, combination_list, lsrc)

Thanks!

+1  A: 

For your first question, you can define a function composition operation like this:

def compose(f, g):
    return lambda *x: f(g(*x))

Then, you can:

ra = compose(rangeset_001, algo_001)
ra(lsrc)

If you make lists of functions like this:

rangesets = [rangeset_001, rangeset_002, rangeset_003]

then you can iterate:

for r in rangesets:
    ra = compose(r, algo_001)
    ra(lsrc)

Expansion of this idea to the algo_xxx functions is also possible.

Greg Hewgill
thanks Gerg, may I know if the lambda can support variable parameters? for example a list be given?
user478514
Why not use `def composed(*args, **kwargs): ...` and `return composed` instead?
detly
@user478514: Yes, I'll change my example to show that using the Python `*` notation.
Greg Hewgill
@Greg Hewgill, thanks, but I means, if I has already use composed() to make a ra list, can I chain and invoke them looks like ldst = ra[0](ra[1](ra[2](lsrc))) with lambda in some way?
user478514
Sorry, I haven't a clue what you mean when you index that like `ra[0]`. In my example `ra` is a *function*, not a *list*.
Greg Hewgill