我正在尝试减少以下二项式和的计算:
def binomial(m, k):
result = 1
for i in range(k):
result = result * (m - i) / (i + 1)
return result
n, t = 10, 20
bin2 = binomial(n + t, n)
for i in xrange(n + 1):
bin2 = binomial(n + t - i, n) # recalculation here.
# bin2 = bin2 * (t - i) / (n + t - i) my wrong implementation
print bin2
我不喜欢的是在循环期间我应该使用先前计算的bin2重新计算bin2。我知道我必须使用here ,
中的公式但我的错误实现给出了错误的结果。任何想法我应该如何简化它?
答案 0 :(得分:2)
您有一个错误的错误。更新前打印。
def binomial(m, k):
result = 1
for i in range(k):
result = result * (m - i) / (i + 1)
return result
n, t = 10, 20
bin2 = binomial(n + t, n)
for i in xrange(n + 1):
print bin2
bin2 = bin2 * (t - i) / (n + t - i)
答案 1 :(得分:0)
您可以在二项式函数中使用yield
代替return
,以使迭代器包含您的数字的所有二项式:
>>> def binomial(m, k):
... result = 1
... for i in range(k):
... result = result * (m - i) / (i + 1)
... yield result
...
>>> list(binomial(6,3))
[6, 15, 20]
然后当您想根据for循环计算bin(30,10)
到bin(20,10)
时,您可以将列表切片并反转:
>>> list(binomial(n,t))[-t:][::-1]
答案 2 :(得分:0)
您可以使用函数属性来保存以前的结果,并在函数的计算中使用它:
def foo(n):
x = foo.previous + n
foo.previous = x
return x
foo.previous = 0
for n in xrange(5):
print foo.previous, foo(n)
>>>
0 0
0 1
1 3
3 6
6 10
>>>
或使用装饰者:
import functools
def wraps(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
try:
p = f.previous
except AttributeError as e:
p = 0
kwargs['previous'] = p
result = f(*args, **kwargs)
f.previous = result
return result
return wrapper
@wraps
def foo(n, previous = None):
return n + previous
>>>
>>> foo(2)
2
>>> foo(2)
4
>>> foo(2)
6
>>> foo(2)
8
>>>