使用sympy
我有两个列表:
terms = [1, x, x*(x-1)]
coefficients = [-1,8.1,7]
我需要获得输出:
-1+8.1*x+7*x(x-1)
我试过了:
print (sum(a,x__i) for a, x__i in izip(terminos,coeficientes))
但实际上我有一个generator
,我根据工作代码尝试了这个:
def lag_l(xx, j):
x = Symbol("x")
parts = ((x - x_i) / (xx[j] - x_i) for i, x_i in enumerate(xx) if i != j)
return prod(parts)
def lag_L(xx, yy):
return sum(y*lag_l(xx, j) for j, y in enumerate(yy))
我该如何完成?
答案 0 :(得分:3)
In [159]: import sympy as sy
In [160]: from sympy.abc import x
In [161]: terms = [1, x, x*(x-1)]
In [162]: coefficients = [-1,8.1,7]
In [163]: sum(t*c for t, c in zip(terms, coefficients))
Out[163]: 7*x*(x - 1) + 8.1*x - 1
有趣的是,sum(term*coef for term, coef in zip(terms, coefficients))
比sum(coef * term for coef, term in zip(coefficients, terms))
快一点:
In [182]: %timeit sum(term * coef for term, coef in zip(terms, coefficients))
10000 loops, best of 3: 34.1 µs per loop
In [183]: %timeit sum(coef * term for coef, term in zip(coefficients, terms))
10000 loops, best of 3: 38.7 µs per loop
原因是coef * term
调用coef.__mul__(term)
然后必须调用term.__rmul__(coef)
,因为它不知道如何与sympy
符号相乘。额外的函数调用使coef * term
慢于term * coef
。 (term * coef
直接致电term.__mul__(coef)
。)
以下是一些更多的微基准测试:
In [178]: %timeit sum(IT.imap(op.mul, coefficients, terms))
10000 loops, best of 3: 38 µs per loop
In [186]: %timeit sum(IT.imap(op.mul, terms, coefficients))
10000 loops, best of 3: 32.8 µs per loop
In [179]: %timeit sum(map(op.mul, coefficients, terms))
10000 loops, best of 3: 38.5 µs per loop
In [188]: %timeit sum(map(op.mul, terms, coefficients))
10000 loops, best of 3: 33.3 µs per loop
请注意terms
和coefficients
的顺序很重要,但除此之外,这些变体之间几乎没有时间差异。对于更大的输入,它们也表现相同:
In [203]: terms = [1, x, x*(x-1)] * 100000
In [204]: coefficients = [-1,8.1,7] * 100000
In [205]: %timeit sum(IT.imap(op.mul, terms, coefficients))
1 loops, best of 3: 3.63 s per loop
In [206]: %timeit sum(term * coef for term, coef in zip(terms, coefficients))
1 loops, best of 3: 3.63 s per loop
In [207]: %timeit sum(map(op.mul, terms, coefficients))
1 loops, best of 3: 3.48 s per loop
另请注意,如果您不知道(通过分析)此操作是代码中的一个关键瓶颈,那么担心这些细微的差异会浪费您的时间,因为预先优化这些东西所需的时间远远大于代码运行时保存的时间。如他们所说,preoptimization is the root of all evil。我可能已经犯了这个罪。
在Python2中,
sum(IT.imap(op.mul, coefficients, terms))
使用最少的内存。
在Python3中,zip
和map
返回迭代器,所以
sum(t*c for t, c in zip(terms, coefficients))
sum(map(op.mul, coefficients, terms))
也会节省内存。
答案 1 :(得分:1)
使用简单的生成器表达式:
sum(coef * term for coef, term in zip(coefficients, terms))
或者,您可以使用与zip
类似的内容而非使用zip_with
:
def zip_with(operation, *iterables):
for elements in zip(*iterables):
yield operation(*elements)
并将其用作:
import operator as op
sum(zip_with(op.mul, coefficients, terms))
正如unutbu提到的python已经在python2下的itertools.imap
和python3中的内置'map
中提供了这样的函数,所以你可以避免重写它并使用:
sum(itertools.imap(op.mul, coefficients, terms))
或
sum(map(op.mul, coefficients, terms) #python3
当你传递多个序列并且长度不同时, python 2 map
的工作方式略有不同。