def function_1(arr):
return [j for i in range(len(arr)) for j in range(len(arr))
if np.array(arr)[i] == np.sort(arr)[::-1][j]]
给出一个arrarr
数组。每个位置[i]
都需要在arriarri
数组中找到arrarr
元素编号,并按降序排列。 arrarr
数组的所有值都不相同。
我必须写1行func。它正在工作,但是非常缓慢。我必须这样做:
np.random.seed(42)
arr = function_1(np.random.uniform(size=1000000))
print(arr[7] + arr[42] + arr[445677] + arr[53422])
请帮助优化代码。
答案 0 :(得分:1)
您反复对数组进行排序和反转,但是该操作的结果与i
或j
的当前值无关。简单的事情是预先计算它,然后在列表推导中使用它的值。
为此,range(len(arr))
也可以计算一次。
最后,arr
已经是一个数组;您不需要每次都通过i
循环进行复制。
def function_1(arr):
arr_sr = np.sort(arr)[::-1]
r = range(len(arr))
return [j for i in r for j in r if arr[i] == arr_sr[j]]
将其设置为一行变得比较棘手。除了极度人为的外部约束外,没有任何理由这样做,但是一旦发布了Python 3.8,赋值表达式将使其变得更容易。我认为以下内容是等效的。
def function_1(arr):
return [j for i in (r:=range(len(arr))) for j in r if arr[i] == (arr_sr:=np.sort(arr)[::-1])[j]]
答案 1 :(得分:0)
考虑一下此处正在进行的步骤:
[j
for i in range(len(arr))
for j in range(len(arr))
if np.array(arr)[i] == np.sort(arr)[::-1][j]
]
假设您的数组包含 N 个元素。
您选择一个i
, N 个不同的时间
您选择了j
个 N 个不同的时间
然后,对于每个(i,j)
对,您都要执行最后一行。
也就是说,您正在做最后一行 N ^ 2 次。
但是在最后一行中,您正在对包含 N 个元素的数组进行排序。那是一个NlogN操作。因此,您的代码的复杂度为O(N ^ 3.logN)。
在调用[... for i ... for j ...]之前,尝试对数组进行排序。这样可以将时间复杂度降低为O(N ^ 2 + NlogN)
我认为...