如何为100000次迭代优化python循环?

时间:2019-10-23 06:52:42

标签: python python-3.x optimization

我是python的新手,我正在尝试编写一个函数,其描述如下: 我有一个整数列表。从此列表中,我必须找到频率最高的项目并将其打印出来。 除非我有一个限制,该功能必须在10秒内完成执行并且应该消耗<512 MB 的内存,否则这似乎很简单。对于较短的列表,我的函数可以正常工作,但对于长度为100000的列表,则可以运行。我无法优化代码。 我有2种实现方式:

实施#1

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

例如

if ar = [3 2 1 3]
o/p: 2

在这里不能使用NumPy。 (不能使用外部软件包)

6 个答案:

答案 0 :(得分:3)

内置Counter最简单(且相当快):

from collections import Counter
winner = Counter(ar).most_common(1)[0]

this article中给出了一种甚至更快的方法(不使用额外的内存,但是破坏了原始数组),在此复制:

# 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函数而不是第二个循环。)

答案 1 :(得分:3)

希望这会有所帮助!

我们正在使用Python的高性能容器数据类型(Counter

from collections import Counter

def returnMaxFrequency(ar):
    return max(Counter(t).values())

Counter对您的号码进行频率映射并创建了dict,一旦创建了dict,您就使用max获取列表的最大频率。

除非您要使用分布式计算解决方案,否则使用Dict是产生频率计数的有效方法

注意:collections是python内置软件包,即带有安装程序。不是外部库。

答案 2 :(得分:2)

两个实现基本相同,第二个仅使用列表压缩而不是for循环。两种算法都在O(n^2)中,因为countO(n)中,并且您将其调用n次(每个值一次)。

如果要进行优化,请将复杂度降低到O(n)

def returnMaxFrequency(ar):   
    freqDict = {x:0 for x in ar}
    for val in ar:
        freqDict[val] = freqDict[val] + 1
    maxFreq = max(freqDict.values())
    return maxFreq

答案 3 :(得分:1)

返回list中最频繁出现的值

max(set(ar), key=ar.count) 

答案 4 :(得分:0)

那呢?

max(ar.count(i) for i in ar)

还是这个?:

max(map(ar.count,ar))

答案 5 :(得分:0)

第二种工具很好,但是在dict-comprehension内部将ar更改为set(ar),它将仅检查每个项目一次:

def returnMaxFrequency(ar):   
    freqDict = {x:ar.count(x) for x in set(ar)}   
    maxFreq = max(freqDict.values())
    return maxFreq