[英]How can I optimize my Python code to run faster?
如果在其右侧的每个元素(不仅仅是紧邻其右侧的一个元素)都严格小于该元素,则将项目列表的元素定义为支配者。 请注意,根据这个定义,列表的最后一项自动成为支配者。 这个 function 应该计算项目中有多少元素是支配者,并返回该计数。 例如,列表
[42, 7, 12, 9, 13, 5]
的支配者将是元素42
、13
和5
。 列表的最后一个元素是微不足道的支配者,不管它的值如何,因为它后面没有更大的元素。
我正在解决这个练习问题并且有一个有效的代码,但是它很慢。 我怎样才能最好地优化它以更快地运行?
def count_dominators(items):
item_count = len(items)
count = 0
if item_count==0:
return count;
count+=1;
if item_count==1:
return count;
for i in range(0,len(items)-1):
flag=1
for j in range(i+1,len(items)):
if(items[j]>=items[i]):
flag=0;
break;
if(flag==1):
count+=1;
return count
import numpy as np
seq=[42, 7, 12, 9, 13, 5]
dominators=np.unique(np.maximum.accumulate(seq[::-1]))
print(dominators)
>>>[ 5 13 42]
以相反的顺序迭代会将其从O(n²)
减少到O(n)
,因为您将在 go 中保持运行最大值,而无需重新扫描每个新元素的所有尾随元素。 因此,无需依赖您未编写的复杂实用程序,您只需执行以下操作:
def count_dominators(items):
max_so_far = float('-inf') # Smaller than any value to it's replaced immediately,
# identifying first element as dominator by definition
count = 0
for item in reversed(items): # Iterate in reverse order so we only need to know max
# so far to identify new dominators
if item > max_so_far:
max_so_far = item
count += 1
return count
如果你想要更多的魔法来减少自己的工作,Python 的itertools
模块提供了一个accumulate
function ,它可以在元素上重复执行操作,产生迄今为止的结果。 如果你使用max
作为操作,那么它会生成一个 stream 数字,只有当你看到一个新的支配者时才会改变。 将结果转换为一个set
或使用itertools.groupby
(在没有 arguments 的情况下运行时大致相当于uniq
命令行实用程序,使其成为对相邻重复项进行重复数据删除的廉价方法)进行重复数据删除,以及该set
的长度或数量groups 是支配者计数:
from itertools import accumulate, groupby
def count_dominators(items):
return sum(1 for _, _ in groupby(accumulate(reversed(items), max)))
或者以技术上不必要的为代价,为每个新的支配者set
增长(可能更快,因为itertools.groupby
的开销比您预期的要多,并且重复数据删除后收集的元素数量可能小到无关紧要):
from itertools import accumulate
def count_dominators(items):
return len(set(accumulate(reversed(items), max)))
如果您愿意,您可以将sum(1 for _, _ in
(以及匹配的尾括号)替换为更有效的方法来计算迭代器中的元素(尽管除非输入很大,否则几乎无关紧要)。
假设只有正数,您可以从列表的末尾开始运行并标记您遇到的最大数字。 这将是 O(n) 复杂性,而不是您建议的 O(n^2)。 像这样的东西会起作用:
def count_dominators(items):
count = 0
last_biggest = -1
for i in range(len(items)-1,-1,-1):
if items[i] > last_biggest:
last_biggest = items[i]
count += 1
return count
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.