[英]Sum of products of all pairs in a list
I want to sum the products of all distinct pairs in a list.我想对列表中所有不同对的乘积求和。 I wrote the following code that counts correctly this:
1*2 + 1*3 + 1*4 + 2*3 + 2*4 + 3*4
我编写了以下正确计数的代码:
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))
When I try to change list to l = [1, 1, 1, 1]
it returns 12 (and not 6).当我尝试将列表更改为
l = [1, 1, 1, 1]
时,它返回 12(而不是 6)。
Why is this happening?为什么会这样?
The immediate issue is that you are using ls.index
to find where to start the inner loop.直接的问题是您正在使用
ls.index
来查找从哪里开始内部循环。 list.index
returns the index of the first matching item, so will only do what you want if there are no duplicates in the list. list.index
返回第一个匹配项的索引,因此只有在列表中没有重复项时才会执行您想要的操作。 Another problem is that it performs a linear search of your list for every iteration of the outer loop, making your algorithm needlessly inefficient.另一个问题是它对外部循环的每次迭代执行列表的线性搜索,使您的算法不必要地低效。
A number of workarounds are available.有许多解决方法可用。 A simple one is using
enumerate
to follow along with the index that you want:一个简单的方法是使用
enumerate
跟随您想要的索引:
sum(n * ls[j] for i, n in enumerate(ls) for j in range(i + 1, len(ls)))
Or you could use a pair of range
objects:或者您可以使用一对
range
对象:
sum(ls[i] * ls[j] for i in range(len(ls)) for j in range(i + 1, len(ls)))
Creating a range
is generally cheaper than copying out the entire sublist every time, as with创建一个
range
通常比每次都复制整个子列表便宜,就像
sum(x * y for i, x in enumerate(ls) for y in ls[i + 1:])
Alternatively, you could use itertools.combinations
to generate the values for you a bit more efficiently:或者,您可以使用
itertools.combinations
更有效地为您生成值:
sum(x * y for x, y in itertools.combinations(ls, 2))
Instead, use the following short approach with itertools.starmap
and itertools.combinations
features:相反,请使用以下带有
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.