目录
一、前言
最近在项目中应用python的推导式比较多,主要是考虑到推导式很简洁,且可读性高,所以没有用filter。有空了忽然想比较分析一下python推导式和filter性能的比较。最终结果让我还挺开心,看来用推导式路子选对了(虽然这点效率提升可忽略不计)。后文也抛出了一个疑问,希望能一起探讨。
二、代码
import datetime
# 生成一千万的列表用于测试
testList = [x for x in range(10000000)]
def func_tuidao():
startTime = datetime.datetime.now()
cnt = 10 # 循环次数
newlist = []
while cnt > 0:
newlist = [item for item in testList if item % 3 == 0]
cnt -= 1
endTime = datetime.datetime.now()
print('推导式耗时: %s' % (endTime - startTime))
def func_filter():
startTime = datetime.datetime.now()
cnt = 10 # 循环次数
newlist = []
while cnt > 0:
newlist = list(filter(lambda item: item % 3 == 0, testList))
cnt -= 1
endTime = datetime.datetime.now()
print('filter耗时: %s' % (endTime - startTime))
func_tuidao()
func_filter()
三、结果
本地用1000W的记录测试结果如下,测试了六次,推导式耗时基本在6.5秒左右,但filter加lambda耗时在13秒左右,近乎推导式的两倍。CPU和内存未满载。
四、另一个样例
import datetime
# 生成一千万的列表用于测试
testList = [x for x in range(10000000)]
def func_filter():
startTime = datetime.datetime.now()
cnt = 10
newlist = []
while cnt > 0:
newlist = list(filter(lambda item: item % 3 == 0, testList))
cnt -= 1
endTime = datetime.datetime.now()
print('filter耗时: %s' % (endTime - startTime))
def func_filter2():
startTime = datetime.datetime.now()
cnt = 10
newlist = []
while cnt > 0:
# 与func_filter区别仅在于此,不立即生成列表
newlist = filter(lambda item: item % 3 == 0, testList)
cnt -= 1
endTime = datetime.datetime.now()
print('filter2耗时: %s' % (endTime - startTime))
func_filter()
func_filter2()
执行结果:func_filter2()运行耗时为0了。
怎么会为0了呢?让我们再进一步用代码分析:
import datetime
# 此处列表大小就改小一点了,我们打印出来结果看
testList = [x for x in range(1000)]
def func_filter2():
startTime = datetime.datetime.now()
cnt = 10
newlist = []
while cnt > 0:
# 与func_filter区别仅在于此,不立即生成列表
newlist = filter(lambda item: item % 3 == 0, testList)
print('----------L', cnt)
print(newlist)
print(type(newlist))
cnt -= 1
print('******************')
tmp = list(newlist)
print(tmp)
print(type(tmp))
endTime = datetime.datetime.now()
print('filter2耗时: %s' % (endTime - startTime))
func_filter2()
运行结果:可看到filter的返回结果是一个filter对象。此结果有如下可能(暂时还没找到权威有效答案,欢迎评论区探讨):
1、看来真正耗时的阶段是生成列表时,而不是筛选过滤的时候?
2、filter的返回结果只是一个类对象,并未真正执行后面的过滤,等到后面执行到list(newList)时,才会开始去执行?
五、结论
1、推导式可读性比filter加lambda更高,且更简洁。
2、推导式耗时更小。