列表中所有成对产品的总和

时间:2019-10-28 14:58:11

标签: python python-3.x list-comprehension

我想对列表中所有不同对的乘积求和。我编写了以下代码来正确计数:1*2 + 1*3 + 1*4 + 2*3 + 2*4 + 3*4

l = [1, 2, 3, 4]
def sum_of_pairs(ls):
    return sum([x * y for x in ls for y in ls[ls.index(x) + 1:]])
print(sum_of_pairs(l))

当我尝试将列表更改为l = [1, 1, 1, 1]时,它将返回12(而不是6)。

为什么会这样?

2 个答案:

答案 0 :(得分:2)

当前的问题是您正在使用ls.index查找从哪里开始内循环。 list.index返回 first 匹配项的索引,因此,如果列表中没有重复项,则只会执行您想要的操作。另一个问题是,它会对外循环的每次迭代执行列表的线性搜索,从而使算法不必要地效率低下。

有许多解决方法。一种简单的方法是使用enumerate跟随所需的索引:

sum(n * ls[j] for i, n in enumerate(ls) for j in range(i + 1, len(ls)))

或者您可以使用一对range对象:

sum(ls[i] * ls[j] for i in range(len(ls)) for j in range(i + 1, len(ls)))

创建range通常比每次复制整个子列表都要便宜,

 sum(x * y for i, x in enumerate(ls) for y in ls[i + 1:])

或者,您可以使用itertools.combinations为您更有效地生成值:

sum(x * y for x, y in itertools.combinations(ls, 2))

答案 1 :(得分:2)

相反,对itertools.starmapitertools.combinations功能使用以下简短方法:

from itertools import starmap, combinations
from operator import mul

def sum_of_pairs(lst):
    return sum(starmap(mul, combinations(lst, 2)))

print(sum_of_pairs([1, 2, 3, 4]))   # 35
print(sum_of_pairs([1, 1, 1, 1]))   # 6