问题描述
我最近发布了一个使用 lambda 函数的问题,在回复中有人提到 lambda 已不再受欢迎,而是使用列表推导.我对 Python 比较陌生.我做了一个简单的测试:
I recently posted a question using a lambda function and in a reply someone had mentioned lambda is going out of favor, to use list comprehensions instead. I am relatively new to Python. I ran a simple test:
import time
S=[x for x in range(1000000)]
T=[y**2 for y in range(300)]
#
#
time1 = time.time()
N=[x for x in S for y in T if x==y]
time2 = time.time()
print 'time diff [x for x in S for y in T if x==y]=', time2-time1
#print N
#
#
time1 = time.time()
N=filter(lambda x:x in S,T)
time2 = time.time()
print 'time diff filter(lambda x:x in S,T)=', time2-time1
#print N
#
#
#http://snipt.net/voyeg3r/python-intersect-lists/
time1 = time.time()
N = [val for val in S if val in T]
time2 = time.time()
print 'time diff [val for val in S if val in T]=', time2-time1
#print N
#
#
time1 = time.time()
N= list(set(S) & set(T))
time2 = time.time()
print 'time diff list(set(S) & set(T))=', time2-time1
#print N #the results will be unordered as compared to the other ways!!!
#
#
time1 = time.time()
N=[]
for x in S:
for y in T:
if x==y:
N.append(x)
time2 = time.time()
print 'time diff using traditional for loop', time2-time1
#print N
它们都打印相同的 N,所以我评论了 print stmt out(除了最后一种方式是无序的),但是在重复测试中产生的时间差异很有趣,如以下示例所示:
They all print the same N so I commented that print stmt out (except the last way it's unordered), but the resulting time differences were interesting over repeated tests as seen in this one example:
time diff [x for x in S for y in T if x==y]= 54.875
time diff filter(lambda x:x in S,T)= 0.391000032425
time diff [val for val in S if val in T]= 12.6089999676
time diff list(set(S) & set(T))= 0.125
time diff using traditional for loop 54.7970001698
因此,虽然我发现列表推导总体上更易于阅读,但至少在此示例中似乎存在一些性能问题.
So while I find list comprehensions on the whole easier to read, there seems to be some performance issues at least in this example.
那么,两个问题:
为什么 lambda 等被搁置一旁?
Why is lambda etc being pushed aside?
对于列表理解方式,是否有更高效的实现方式?如果不进行测试,您怎么知道它更高效?我的意思是,由于额外的函数调用,lambda/map/filter 应该效率较低,但它似乎更有效.
For the list comprehension ways, is there a more efficient implementation and how would you KNOW it's more efficient without testing? I mean, lambda/map/filter was supposed to be less efficient because of the extra function calls, but it seems to be MORE efficient.
保罗
推荐答案
你的测试做了非常不同的事情.其中 S 为 1M 元素,T 为 300:
Your tests are doing very different things. With S being 1M elements and T being 300:
[x for x in S for y in T if x==y]= 54.875
此选项进行 300M 的相等比较.
This option does 300M equality comparisons.
filter(lambda x:x in S,T)= 0.391000032425
此选项通过 S 进行 300 次线性搜索.
This option does 300 linear searches through S.
[val for val in S if val in T]= 12.6089999676
此选项通过 T 进行 1M 线性搜索.
This option does 1M linear searches through T.
list(set(S) & set(T))= 0.125
此选项执行两个集合构造和一个集合交集.
This option does two set constructions and one set intersection.
这些选项之间的性能差异更多地与每个选项使用的算法有关,而不是列表推导式和 lambda
之间的任何差异.
The differences in performance between these options is much more related to the algorithms each one is using, rather than any difference between list comprehensions and lambda
.
这篇关于lambda 与列表理解性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!