2010-10-26 4 views
1

en python I fonctions définies:Liste de fonctions python chaînée en cours d'exécution?

def foo_1(p): return p + 1 
def foo_2(p): return p + 1 
def foo_3(p): return p + 1 
def foo_4(p): return p + 1 
def foo_5(p): return p + 1 

J'ai besoin d'exécuter les fonctions comme une chaîne peut, comme ceci:

foo_1(foo_2(foo_3(foo_4(foo_5(1))))) 

Puis-je savoir si je peux pousser les fonctions dans une liste puis exécuter ces fonctions en tant que chaîne, peut-être aussi je peux donner une séquence d'exécution?

lf = [Null,foo_1,foo_2,foo_3,foo_4,foo_5] # Null is for +1 issue here 

def execu(lst, seq, raw_para): 
    # in some way 

execu(lf,(1,2,3,4,5), 1) # = foo_1(foo_2(foo_3(foo_4(foo_5(1))))) 
execu(lf,(1,2,3), 1)  # = foo_1(foo_2(foo_3(1))) 
execu(lf,(3,3,3), 1)  # = foo_3(foo_3(foo_3(1))) 

Merci!

RBP,

KC

Répondre

3
def execu(lst, seq, raw_para): 
    return reduce(lambda x, y: y(x), reversed(operator.itemgetter(*seq)(lst)), raw_para) 
+0

Pourquoi inverser ici? –

+0

'reduce()' gère les éléments du début à la fin. Votre exemple montre qu'ils sont invoqués de bout en bout. –

+0

ah, IC, la pile devrait de bout en bout, merci –

4

Vous pouvez utiliser reduce pour cela:

reduce(lambda x, y: y(x), list_of_functions, initial_value) 

comme ceci:

reduce(lambda x, y: y(x), reversed([foo_1, foo_2, foo_3, ...]), 1) 

Notez que si vous souhaitez appliquer la les fonctions Dans l'ordre foo_1(foo_2(etc...)), vous devez vous assurer que foo_1 est le dernier élément de la liste des fonctions. Par conséquent, j'utilise reversed dans le dernier exemple.

+0

Malheureusement, cela va composer les fonctions dans le mauvais ordre. '... (foo_3 (foo_2 (foo_1 (1))))' –

+0

Bon appel, Ignacio, je vais ajouter un appel 'reverse'. –

4

Pas besoin de "Null" dans "lf".

def execu(lst, seq, raw_para): 
    para = raw_para 
    for i in reversed(seq): 
     para = lst[i](para) 
    return para 
+0

+1, mais je pense que le premier Aucun (Null?) Est requis, ou utiliser les valeurs 'seq' –

+0

'seq' sont des index dans' lst', donc aucune modification n'est nécessaire ici. Au contraire, si vous supprimez le None inutile de la liste OP, vous devez également déplacer les index vers le bas pour les faire correspondre. Je suggère de supprimer 'para' et de renommer' raw_para' en 'para' pour simplifier. –

+1

Ce code doit être la première chose à laquelle tout le monde pense. Je ne sais pas pourquoi tout le monde pensait que c'était une amélioration pour amener réduire et lambda dans l'image. –