我工作的项目欧拉问题14 ,并作为第一次尝试我刮起了这个蛮力解决方案:
def collatz(n, memo={1: [1]}):
if n not in memo:
memo[n] = [n] + collatz(3 * n + 1 if n % 2 else n // 2)
return memo[n]
def p014():
return max(xrange(1, 10**6), key=lambda n: len(collatz(n)))
我的问题是关于拉姆达,我通常不愿意使用它们,但我不知道任何优雅的方式,以避免它在这种情况下。 有什么在functools
或其他以链上的两个可调用,或我错过任何其他替代整齐?
如果有一个这将是可爱compose
也许-功能functools
。 没有,我也不指望会有, 唉 。 在雷蒙德的Hettinger的话,
前面已经讨论,并在其他论坛拒绝。 其中一个问题是,通常的数学顺序是直观而不是自我记录-即是compose(f,g)
一样f(g(x))
或g(f(x))
此外,它是已经污垢简单创建自己的撰写功能或直接做组合物: h = lambda x: f(g(x))
这里有两个简单的实现中compose
的,你会发现有用的,可调用的类:
# Scott Daniels, http://code.activestate.com/recipes/52902-function-composition/
# Lightly edited for style.
class Compose(object):
'''Compose functions. compose(f,g,x...)(y...) = f(g(y...),x...))'''
def __init__(self, f, g, *args, **kwargs):
self.f = f
self.g = g
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs)
class Starcompose:
'''Compose functions. Starcompose(f,g,x...)(y...) = f(*g(y...),x...))'''
TupleType = type(())
def __init__(self, f, g, *args, **kwargs):
self.f = f
self.g = g
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
mid = self.g(*args, **kwargs)
if isinstance(mid, self.TupleType):
return self.f(*(mid + self.pending), **self.kwargs)
return self.f(mid, *self.pending, **self.kwargs)
此外,请参阅functional
包,它激发了这个非常简单的compose_many
前一阵子我的功能:
def compose(f1, f2):
def composition(*args, **kwargs):
return f1(f2(*args, **kwargs))
return composition
def compose_many(*funcs):
return reduce(compose, funcs)
这可能是更Python写这作为发电机:
def p014():
length, n = max(
(len(collatz(n)), n)
for n in xrange(1, 10**6)
)
return n
文章来源: Python avoiding lambda for key which needs two callables (function composition)