【问题标题】:Sum of product of combinations in a list列表中组合的乘积之和
【发布时间】:2015-12-23 13:58:22
【问题描述】:

对给定列表中所有组合的乘积求和的 Pythonic 方式是什么,例如:

[1, 2, 3, 4]
--> (1 * 2) + (1 * 3) + (1 * 4) + (2 * 3) + (2 * 4) + (3 * 4) = 35

(对于这个例子,我采用了所有的二元素组合,但它可能会有所不同。)

【问题讨论】:

  • 组合是否必须包含 2 个元素?

标签: python python-3.x functional-programming


【解决方案1】:

使用itertools.combinations

>>> l = [1, 2, 3, 4]
>>> sum([i*j for i,j in list(itertools.combinations(l, 2))])
35

【讨论】:

  • 我无法决定选择哪个答案作为“答案”。凯文的方法在任何方面都优越吗? (也许在更一般的环境中或其他任何情况下。)
  • 不应该是sum([i*j for i,j in list(combinations(l, 2))])吗?
  • @blackened:如果我是你,我会接受 Avinash 的回答,因为他的回答比我的简单明了。我认为我的答案只是使用了更多功能而不是 * 运算符,它并不比 Avinash 快,但更复杂。
  • @JoeR:不,不需要在这里创建另一个列表。
  • @kevin 我以前的代码比现在的要胖。既然我听说了,gen expresion 比 list 不需要更多的循环。
【解决方案2】:
>>> a = [1, 2, 3, 4]    
>>> import operator
>>> import itertools
>>> sum(itertools.starmap(operator.mul, itertools.combinations(l, 2)))
35

itertools.combinations(a, 2) 返回:

>>> list(itertools.combinations(a, 2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
>>> 

itertools.starmap() 确实如此:

创建一个迭代器,使用从可迭代对象获得的参数计算函数。当参数参数已经从单个可迭代的元组中分组(数据已“预压缩”)时,使用而不是 map()

最后,使用sum()generator comprehension 得到最终结果。

【讨论】:

  • 你也可以用itertools.starmap代替reducesum(itertools.starmap(operator.mul, itertools.combinations(l, 2)))
【解决方案3】:

我不确定pythonic的方式,但你可以用更简单的方式解决这个问题。

例如对于一个列表 [a, b, c] => 结果也可以写成

( (a + b + c)^2 - (a^2 + b^2 + c^2) ) / 2

所以,它可以写成列表和的平方和列表的平方和的差除以2。

在python中也可以实现如下:

a = [1,2,3,4]
( (sum(a) ** 2) - sum([x ** 2 for x in a]) ) / 2

附:我知道可以使用 itertools 解决问题,并且问题特别要求使用 pythonic 方法来解决它。我认为不用尝试所有组合就很容易做到。

【讨论】:

    【解决方案4】:

    这也是数组外向量积的上三角与自身之和:

    import numpy as np
    np.triu(np.outer([1,2,3,4],[1,2,3,4]),1).sum()
    35
    

    一步一步的工作是这样的:

    # outer product
    np.outer([1,2,3,4],[1,2,3,4])
    
    array([[ 1,  2,  3,  4],
           [ 2,  4,  6,  8],
           [ 3,  6,  9, 12],
           [ 4,  8, 12, 16]])
    
    # upper triangle
    np.triu(np.outer([1,2,3,4],[1,2,3,4]),1)
    
    array([[ 0,  2,  3,  4],
           [ 0,  0,  6,  8],
           [ 0,  0,  0, 12],
           [ 0,  0,  0,  0]])
    
    # then the sum, which is the non-zero elements
    np.triu(np.outer([1,2,3,4],[1,2,3,4]),1).sum()
    35
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 2016-04-12
      相关资源
      最近更新 更多