如何为100000次迭代优化python循环?
我是python新手,我正在尝试编写一个函数,其描述如下: 我有一个整数列表。从这个列表中,我必须找到最大频率的项目并打印出来。 这看起来很直截了当,除非我有一个限制,即函数必须在10秒内完成执行,并且应该消耗<512 MB的内存。对于较短的列表长度,我的函数可以正常工作,但对于长度为100000的列表,它可以运行。我无法优化代码。 我有两个相同的实现: 实施1如何为100000次迭代优化python循环?,python,python-3.x,optimization,Python,Python 3.x,Optimization,我是python新手,我正在尝试编写一个函数,其描述如下: 我有一个整数列表。从这个列表中,我必须找到最大频率的项目并打印出来。 这看起来很直截了当,除非我有一个限制,即函数必须在10秒内完成执行,并且应该消耗
def returnMaxFrequency(ar):
freqList = []
for val in ar:
freq = ar.count(val)
freqList.append(freq)
return(max(freqList))
实施2
def returnMaxFrequency(ar):
freqDict = {x:ar.count(x) for x in ar}
maxFreq = max(freqDict.values())
return maxFreq
乙二醇
使用NumPy在这里不是一个选项。无法使用外部包返回列表中最常出现的值
返回列表中最常出现的值
两个实现基本相同,第二个实现只使用列表理解而不是for循环。这两种算法都在^2上,因为count在On上,并且您为每个值调用它n次 如果要优化,请将复杂性降低到On:
两个实现基本相同,第二个实现只使用列表理解而不是for循环。这两种算法都在^2上,因为count在On上,并且您为每个值调用它n次 如果要优化,请将复杂性降低到On:
最简单且速度合理的可能是内置计数器: 一种更快的方法,无需使用额外内存,但会破坏原始阵列,请参见,此处复制:
# Python program to find the maximum repeating number
# Returns maximum repeating element in arr[0..n-1].
# The array elements are in range from 0 to k-1
def maxRepeating(arr, n, k):
# Iterate though input array, for every element
# arr[i], increment arr[arr[i]%k] by k
for i in range(0, n):
arr[arr[i]%k] += k
# Find index of the maximum repeating element
max = arr[0]
result = 0
for i in range(1, n):
if arr[i] > max:
max = arr[i]
result = i
# Uncomment this code to get the original array back
#for i in range(0, n):
# arr[i] = arr[i]%k
# Return index of the maximum element
return result
这段代码的一部分可以用更高性能的替代品来代替,特别是使用max函数而不是第二个循环。最简单、速度相当快的可能是内置计数器: 一种更快的方法,无需使用额外内存,但会破坏原始阵列,请参见,此处复制:
# Python program to find the maximum repeating number
# Returns maximum repeating element in arr[0..n-1].
# The array elements are in range from 0 to k-1
def maxRepeating(arr, n, k):
# Iterate though input array, for every element
# arr[i], increment arr[arr[i]%k] by k
for i in range(0, n):
arr[arr[i]%k] += k
# Find index of the maximum repeating element
max = arr[0]
result = 0
for i in range(1, n):
if arr[i] > max:
max = arr[i]
result = i
# Uncomment this code to get the original array back
#for i in range(0, n):
# arr[i] = arr[i]%k
# Return index of the maximum element
return result
这段代码的一部分可以替换为更高性能的替代代码,特别是使用max函数而不是第二个循环。希望这有帮助
我们正在使用Python的高性能容器DataTypesCenter
计数器对您的号码进行频率映射,并创建了一个dict,一旦创建了dict,您就可以使用max来获取列表中的max freq
使用Dict是生成频率计数的有效方法,除非您选择分布式计算解决方案
注意:collections是一个python内置包,即随安装程序提供。不是外部库。希望这有帮助
我们正在使用Python的高性能容器DataTypesCenter
计数器对您的号码进行频率映射,并创建了一个dict,一旦创建了dict,您就可以使用max来获取列表中的max freq
使用Dict是生成频率计数的有效方法,除非您选择分布式计算解决方案
注意:collections是一个python内置包,即随安装程序提供。不是外部库。这个怎么样
max(ar.count(i) for i in ar)
还是这个
max(map(ar.count,ar))
这个怎么样
max(ar.count(i) for i in ar)
还是这个
max(map(ar.count,ar))
第二个工具很好,但是在dict中,将ar更改为setar,并且它只会检查每个项目一次:
def returnMaxFrequency(ar):
freqDict = {x:ar.count(x) for x in set(ar)}
maxFreq = max(freqDict.values())
return maxFreq
第二个工具很好,但是在dict中,将ar更改为setar,并且它只会检查每个项目一次:
def returnMaxFrequency(ar):
freqDict = {x:ar.count(x) for x in set(ar)}
maxFreq = max(freqDict.values())
return maxFreq
看看numba。@DiptangsuGoswami有人提到不能使用外部软件包可以使用内置模块吗?这里提供的答案在哪些方面不能解决您的问题:这尤其是:可能与numba重复。@DiptangsuGoswami有人提到不能使用外部软件包可以使用内置模块吗模块?此处提供的答案在哪些方面不能解决您的问题:这尤其是:您可以使用集合跳过dict初始化。defaultdict.defaultdict不需要跳过字典初始化。dict.getkey,[default=0]将执行。您可以使用集合跳过dict初始化。不需要使用defaultdict.defaultdict跳过字典初始化。dict.getkey,[default=0]will-do他写道他甚至不能使用numpy,因为他不能使用外部package@Aryerez-它是内置包。这里有一个链接供您参考——关于高性能容器数据类型:计数器是用Python实现的,它的性能并不比dict解决方案更好,只是更具可读性和简洁性。不过,这比任何涉及计数的解决方案都要快得多。@Amadan-谢谢!你能证明dict的性能是否比计数器快吗?@Amadan我只是重新运行了中给出的计时,看起来计数器实际上比基于dict和defaultdict的解决方案快,最近的Python版本使用v3.6.7对此进行了测试。他写道,他甚至不能使用numpy,因为他不能使用外部命令package@Aryerez-它是内置包。这里有一个链接供您参考——关于高性能容器数据类型:计数器是用Python实现的,它的性能并不比dict解决方案j更高
更具可读性和简洁性。不过,这比任何涉及计数的解决方案都要快得多。@Amadan-谢谢!你能证明dict的性能是否比计数器快吗?@Amadan我只是重新运行了中给出的计时,看起来计数器实际上比基于dict和defaultdict的解决方案快,最近的Python版本使用v3.6.7对此进行了测试。他写道,他甚至不能使用numpy,因为他不能使用外部命令package@Aryerez:集合不是外部集合他写道,他甚至不能使用numpy,因为他不能使用外部命令package@Aryerez:collections不是外部包。需要添加的是,它具有可怕的算法复杂性。需要添加的是,它具有可怕的算法复杂性。多次迭代输入列表的解决方案较差。迭代输入的解决方案不止一次的列表都是劣质的。
def returnMaxFrequency(ar):
freqDict = {x:ar.count(x) for x in set(ar)}
maxFreq = max(freqDict.values())
return maxFreq