我遇到了一个看似简单的问题,请有人帮忙吗?
我有两个列表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
的所有排列进行求和。
任何人都知道一种优雅的简单方法吗?
答案 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])