J'essaie d'écrire une fonction en python qui ressemble à:
def repeated(f, n):
...
où f
est une fonction qui prend un argument et n
est un entier positif.
Par exemple, si j'ai défini carré comme:
def square(x):
return x * x
et j'ai appelé
repeated(square, 2)(3)
cela équivaudrait 3, 2 fois.
Réponses:
20 pour la réponse № 1Ça devrait le faire:
def repeated(f, n):
def rfun(p):
return reduce(lambda x, _: f(x), xrange(n), p)
return rfun
def square(x):
print "square(%d)" % x
return x * x
print repeated(square, 5)(3)
sortie:
square(3)
square(9)
square(81)
square(6561)
square(43046721)
1853020188851841
ou lambda
-Moins?
def repeated(f, n):
def rfun(p):
acc = p
for _ in xrange(n):
acc = f(acc)
return acc
return rfun
8 pour la réponse № 2
En utilisant reduce
et lamba. Construisez un tuple à partir de votre paramètre, suivi de toutes les fonctions que vous souhaitez appeler:
>>> path = "/a/b/c/d/e/f"
>>> reduce(lambda val,func: func(val), (path,) + (os.path.dirname,) * 3)
"/a/b/c"
2 pour la réponse № 3
Quelque chose comme ça?
def repeat(f, n):
if n==0:
return (lambda x: x)
return (lambda x: f (repeat(f, n-1)(x)))
0 pour la réponse № 4
Je pense que vous voulez une composition fonctionnelle:
def compose(f, x, n):
if n == 0:
return x
return compose(f, f(x), n - 1)
def square(x):
return pow(x, 2)
y = compose(square, 3, 2)
print y
0 pour la réponse № 5
Voici une recette utilisant reduce
:
def power(f, p, myapply = lambda init, g:g(init)):
ff = (f,)*p # tuple of length p containing only f in each slot
return lambda x:reduce(myapply, ff, x)
def square(x):
return x * x
power(square, 2)(3)
#=> 81
J'appelle ça power
, parce que c’est littéralement ce que fait la fonction de pouvoir, la composition remplaçant la multiplication.
(f,)*p
crée un tuple de longueur p
rempli avec f
dans tous les index. Si vous voulez avoir l’imagination, vous utiliseriez un générateur pour générer une telle séquence (voir itertools
) - mais notez qu'il devrait être créé à l'intérieur du lambda.
myapply
est défini dans la liste de paramètres de sorte qu'il ne soit créé qu'une seule fois.
0 pour la réponse № 6
Utilisation de reduction et de itertools.repeat (comme suggéré par Marcin):
from itertools import repeat
from functools import reduce # necessary for python3
def repeated(func, n):
def apply(x, f):
return f(x)
def ret(x):
return reduce(apply, repeat(func, n), x)
return ret
Vous pouvez l'utiliser comme suit:
>>> repeated(os.path.dirname, 3)("/a/b/c/d/e/f")
"/a/b/c"
>>> repeated(square, 5)(3)
1853020188851841
(après importation os
ou définir square
respectivement)
0 pour la réponse № 7
Il existe une recette itertools appelée repeatfunc
qui effectue cette opération.
def repeatfunc(func, times=None, *args):
"""Repeat calls to func with specified arguments.
Example: repeatfunc(random.random)
"""
if times is None:
return starmap(func, repeat(args))
return starmap(func, repeat(args, times))
J'utilise une bibliothèque tierce, more_itertools
, qui implémente commodément ces recettes (facultatif):
import more_itertools as mit
list(mit.repeatfunc(square, 2, 3))
# [9, 9]