我想对列表中所有不同对的乘积求和。我编写了以下代码来正确计数: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)。
为什么会这样?
答案 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.starmap
和itertools.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