带有 kwargs 的递归函数
Recursive function with kwargs
我想要一个递归接受 kwargs 的函数。我怎样才能传递 kwargs?
代码示例:
def recursion(a, b, **kwargs):
if a == 1:
print(a + b)
elif a == 2:
print(a + b + kwargs['name']
else:
a = a/2
recursion(what to put in here?)
def re(a, b, **kwargs):
print(a + b, kwargs['name'])
if a == 0:
return
else:
re(a-b,b,**kwargs)
re(5,1,name='Hello World!')
这将为您提供以下输出
6 Hello World!
5 Hello World!
4 Hello World!
3 Hello World!
2 Hello World!
1 Hello World!
最近遇到了类似的问题,我想出了以下问题:
from functools import wraps
from inspect import currentframe
def recursive_kwargs(fun):
''' Persist keyword arguments through recursive calls '''
@wraps(fun)
def wrapper(*args,**kwargs):
caller_name = currentframe().f_back.f_code.co_name
if caller_name is fun.__name__:
fun(*args,**fun.__kwargs__)
else: # Top of the recursive stack
fun.__kwargs__ = kwargs
fun(*args,**kwargs)
return wrapper
然后你就可以装饰你的函数了,它应该自己工作而不传递任何 kwargs:
@recursive_kwargs
def fib(n, codename='spam', password='eggs'):
print(codename, password)
if n == 1:
return 1
return fib(n-1) # Don't pass any kwargs
现在 fib(3)
returns spam eggs
(3 次),fib(3,codename='Vikings')
确实 return Vikings eggs
(3 次)。
这很可爱也很方便,但是 慢 ,这都是由于 @wraps
和 currentframe
查找。这里有一些 timeit
结果:
fib: [3.69, 3.24, 2.82, 2.57, 2.56] us # As defined above
fib2: [1.45, 1.14, 1.15, 1.08, 1.08] us # With just the @wraps (but doing nothing)
fib3: [0.58, 0.66, 0.68, 0.54, 0.48] us # Just passing the kwargs along manually
TLDR:除非您不关心效率,否则@Harish 的回答可能就是这样做的方法。例如,如果你正在处理一个浅层(恒定深度,甚至)递归堆栈,其中瓶颈是函数本身的主体,而不是递归(又名肯定 而不是 我已经举过的例子在这里使用)。
还有;不要在没有记忆的情况下使用递归来计算斐波那契数(参见 here 了解更多信息)
我想要一个递归接受 kwargs 的函数。我怎样才能传递 kwargs?
代码示例:
def recursion(a, b, **kwargs):
if a == 1:
print(a + b)
elif a == 2:
print(a + b + kwargs['name']
else:
a = a/2
recursion(what to put in here?)
def re(a, b, **kwargs):
print(a + b, kwargs['name'])
if a == 0:
return
else:
re(a-b,b,**kwargs)
re(5,1,name='Hello World!')
这将为您提供以下输出
6 Hello World!
5 Hello World!
4 Hello World!
3 Hello World!
2 Hello World!
1 Hello World!
最近遇到了类似的问题,我想出了以下问题:
from functools import wraps
from inspect import currentframe
def recursive_kwargs(fun):
''' Persist keyword arguments through recursive calls '''
@wraps(fun)
def wrapper(*args,**kwargs):
caller_name = currentframe().f_back.f_code.co_name
if caller_name is fun.__name__:
fun(*args,**fun.__kwargs__)
else: # Top of the recursive stack
fun.__kwargs__ = kwargs
fun(*args,**kwargs)
return wrapper
然后你就可以装饰你的函数了,它应该自己工作而不传递任何 kwargs:
@recursive_kwargs
def fib(n, codename='spam', password='eggs'):
print(codename, password)
if n == 1:
return 1
return fib(n-1) # Don't pass any kwargs
现在 fib(3)
returns spam eggs
(3 次),fib(3,codename='Vikings')
确实 return Vikings eggs
(3 次)。
这很可爱也很方便,但是 慢 ,这都是由于 @wraps
和 currentframe
查找。这里有一些 timeit
结果:
fib: [3.69, 3.24, 2.82, 2.57, 2.56] us # As defined above
fib2: [1.45, 1.14, 1.15, 1.08, 1.08] us # With just the @wraps (but doing nothing)
fib3: [0.58, 0.66, 0.68, 0.54, 0.48] us # Just passing the kwargs along manually
TLDR:除非您不关心效率,否则@Harish 的回答可能就是这样做的方法。例如,如果你正在处理一个浅层(恒定深度,甚至)递归堆栈,其中瓶颈是函数本身的主体,而不是递归(又名肯定 而不是 我已经举过的例子在这里使用)。
还有;不要在没有记忆的情况下使用递归来计算斐波那契数(参见 here 了解更多信息)