[英]Python : summation over all permutations
我遇到了一个看似简单的问题,请有人帮忙吗?
我有两个列表a
和b
。 我可以将列表的元素称为a[i][j]
,其中0<i<100
且0<j<100
。
我想找到所有a[i][j] - b[k][l]
,其中0<i<100, 0<j<100, 0<k<100
且0<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.