我正在练习Codility的一些问题。但是,每次我运行问题时,我的性能(运行时)得分都非常低(25%)。您能帮我知道如何改善我的代码,以便获得更高的分数吗?
问题是:
编写函数:
def solution(A)
给定一个数组N,该数组A由满足上述条件的N个整数组成,则返回未配对元素的值。
例如,给定数组A这样:
A[0] = 9 A[1] = 3 A[2] = 9
A[3] = 3 A[4] = 9 A[5] = 7
A[6] = 9
该函数应返回7,如上面的示例所述。
与我相同的代码是:
def solution(A):
# write your code in Python 3.6
lis=[i for i in A if A.count(i) ==1]
return lis[0]
输出:
medium2 “中等随机测试n = 100,003✘超时错误 被杀达到硬限制:6.000秒”
答案 0 :(得分:4)
这是因为list.count
每次都会搜索整个列表,即O(N)* N或N ** 2。您可以使用collections.Counter
来计数某项一次或一次通过的次数,由于它是字典,因此查找为O(1):
from collections import Counter
def solution(A):
c = Counter(A)
# this will iterate over all the key/value pairs
# which is at worst N elements long
return [k for k, v in c.items() if v==1]
要显示速度增加:
python -m timeit -s "from random import randint; A = [randint(0,500) for i in range(10000)]" "x = [a for a in A if A.count(a)==1]"
10 loops, best of 3: 957 msec per loop
python -m timeit -s "from random import randint; from collections import Counter; A = [randint(0,500) for i in range(10000)]; c = Counter(A)" "x = [s for s, v in c.items() if v==1]"
10000 loops, best of 3: 20.1 usec per loop
即使我每次都创建一个随机列表,但Counter
实现在20个试验中的平均最佳运行时间为20.2us,而list.count
实现为962.1ms。因此,即使每次运行的时间都不尽相同,但我认为平均值可以显示
答案 1 :(得分:2)
使用itertools.groupby()
的版本的性能大约是使用collections.Counter
的版本的3倍:
import collections
from itertools import groupby
import timeit
l = [9, 3, 9, 3, 9, 7, 9]
def fn1(lst):
return [v for v, g in groupby(sorted(lst)) if len([*g]) == 1]
def fn2(lst):
k = collections.Counter(lst)
return [i for i in k if k[i] == 1]
print(timeit.timeit(lambda: fn1(l), number=100_000, globals=globals()) )
print(timeit.timeit(lambda: fn2(l), number=100_000, globals=globals()) )
打印:
0.11646193999331445
0.33489679799822625
答案 2 :(得分:0)
尝试以下方法:
import collections
k = collections.Counter(A)
return [ i for i in k if k[i] == 1]