简体   繁体   English

列表中所有对的乘积之和

[英]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.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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM