Python:对所有排列求和

时间:2015-02-19 14:35:53

标签: python list

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

我有两个列表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的所有排列进行求和。

任何人都知道一种优雅的简单方法吗?

3 个答案:

答案 0 :(得分:3)

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循环。它将从(i, j, k, l)(1, 1, 1, 1)的每个(99, 99, 99, 99)元组上运行。 这将跳过零,您似乎已经要求。

答案 1 :(得分:2)

这样更快:

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

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

我还没有证明它( 编辑 here's a proof outline),只使用两个随机100x100阵列进行了测试,但如果你考虑一下它会很直观它

上面的代码将像Kevin指出的那样,假设您的数组是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

答案 2 :(得分:0)

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

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])