使用python在两个列表中生成产品总和?

时间:2014-03-14 21:26:11

标签: python sympy

使用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))

我该如何完成?

2 个答案:

答案 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

请注意termscoefficients的顺序很重要,但除此之外,这些变体之间几乎没有时间差异。对于更大的输入,它们也表现相同:

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中,zipmap返回迭代器,所以

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的工作方式略有不同。