Composer des fonctions en python
J'ai un tableau de fonctions et je suis en train de produire une fonction qui consiste en la composition des éléments dans mon tableau.
Mon approche est la suivante:
def compose(list):
if len(list) == 1:
return lambda x:list[0](x)
list.reverse()
final=lambda x:x
for f in list:
final=lambda x:f(final(x))
return final
Cette méthode ne semble être au travail, de l'aide sera appréciée.
(Je suis en inversant la liste parce que c'est l'ordre de la composition, je veux les fonctions de l'être)
source d'informationauteur Starless
Vous devez vous connecter pour publier un commentaire.
Cela ne fonctionne pas car toutes les fonctions anonymes que vous créez dans la boucle reportez-vous à la même variable de boucle et donc de partager sa valeur finale.
Comme une solution rapide, vous pouvez remplacer l'affectation:
Ou, vous pouvez retourner le lambda à partir d'une fonction:
De comprendre ce qu'il se passe, essayez cette expérience:
Ce résultat surprend beaucoup de gens, qui attendent le résultat à
[0, 1, 2, ...]
. Cependant, tous les lambdas point à la mêmen
variable, et tous se réfèrent à sa valeur finale, qui est de 9. Dans votre cas, toutes les versions definal
qui sont censés nid finissent en se référant à la mêmef
et, pire encore, à la mêmefinal
.Le sujet de lambdas et pour les boucles en Python a été déjà couverts sur DONC.
L'approche la plus simple serait le premier à écrire une composition de 2 fonctions:
Et ensuite utiliser
reduce
pour composer plus de fonctions:Ou vous pouvez utiliser certains de la bibliothèquequi contient déjà composer fonction.
Exemple:
Récursive de la mise en œuvre de
Voici un appel récursif à la mise en œuvre, je l'ai pas encore vu:
Je ne vous attendez pas à être très performant, même si, comme il fait à nouveau un n-uplet d'arguments à chaque appel récursif.
Comparaison de toutes les suggestions:
Nous allons tester certains de ces implémentations et de déterminer lequel est le plus performant, tout d'abord, quelques seul argument des fonctions (Merci poke):
Voici nos implémentations, je soupçonne que le itératif version est la deuxième plus efficace (manuel de composer sera naturellement plus rapide).
Et de les tester:
Résultats
Et nous obtenons le résultat suivant (même ampleur et de la proportion en Python 2 et 3):
Et mes attentes ont été confirmés: le plus rapide est bien sûr, le manuel, la fonction de composition suivie par l'itératif de mise en œuvre. Une version récursive est beaucoup plus lente, probablement depuis une nouvelle trame de pile est créé par chaque appel de fonction et un nouveau tuple de fonctions est créé pour chaque fonction.
Un liner:
Exemple d'utilisation:
Poke la réponse est bonne, mais vous pouvez également utiliser le
functional
paquet est livré avec un composer de la méthode.Vous pouvez également créer un tableau de fonctions et l'utilisation de réduire:
C'est ma version
Un exemple de la façon dont il est utilisé
Le plus fiable de la mise en œuvre que j'ai trouvé est dans la 3ème partie de la bibliothèque de
toolz
. Lecompose
fonction de cette bibliothèque traite également de la docstring pour la composition de fonctions.La le code source est disponible gratuitement. Ci-dessous est un exemple simple d'utilisation.