繁体   English   中英

Python:对所有排列求和

[英]Python : summation over all permutations

我遇到了一个看似简单的问题,请有人帮忙吗?

我有两个列表ab 我可以将列表的元素称为a[i][j] ,其中0<i<1000<j<100

我想找到所有a[i][j] - b[k][l] ,其中0<i<100, 0<j<100, 0<k<1000<l<100 然后对i, j, k, l 所有排列求和

谁知道一个优雅简单的方法?

import itertools
sum(a[i][j] - b[k][l] for i, j, k, l in itertools.product(range(1, 100), repeat=4))

itertools.product相当于嵌套的for循环。 它将遍历从(1, 1, 1, 1) 1,1,1,1 (1, 1, 1, 1)(99, 99, 99, 99) (1, 1, 1, 1)每个(i, j, k, l)元组。 这将跳过零 ,你似乎已经要求了。

这样更快:

(sum(map(sum, a)) - sum(map(sum, b))) * len(a) * len(b)

因为您正在计算数组总差异的总和。 它将在O(n)中起作用,但Kevin使用itertools的答案是O(n ^ 2)。

我还没有证明它( 编辑这是一个校对大纲 ),只使用两个随机的100x100阵列进行测试,但如果你考虑一下它就会很直观。

上面的代码,就像凯文指出的那样,假设你的数组是100x100并且将包括0.我假设你只是想使用两个100x100数组并且有点搞砸 - 如果你真的想跳过0并且不要不知道数组的大小,那么你可以使用以下代码片段:

from itertools import product

C = 100

def _sum(arr, a, b):
    return sum(arr[i][j] for i, j in itertools.product(range(a, b), repeat=2))

answer = (_sum(a, 1, C) - _sum(b, 1, C)) * (C-1)**2

不是很漂亮,因为我们在子矩阵上迭代,但仍然很快。 如果你想使用numpy ,可以更简洁地编写切片版本:

import numpy as np
A = np.array(a, np.int32)
B = np.array(b, np.int32)
answer = (np.sum(A[1:100, 1:100]) - np.sum(B[1:100, 1:100])) * 99**2

尝试生成数组范围的笛卡尔乘积以获得索引。

import itertools

cprod = itertools.product(range(1, 100, 1), range(1, 100, 1), range(1, 100, 1), range(1, 100, 1))
result = sum([a[cp[0]][cp[1] - b[cp[2]][cp[3] for cp in cprod])

暂无
暂无

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

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