我有一个应用程序,其中有一个对象列表,我需要创建一些对象的子列表,其中一些属性是最小的。我自然而然地开始编写for thing in list:
类型代码,然后想知道我是否值得了解我不时阅读的这些地图和过滤功能,但现在却被忽略了。
任务似乎分为两个阶段,找到最小值,然后创建子列表。除非我对列表进行排序,否则我可以将结果切片,如果我能想到一个快速找到切片位置的方法。
这是我的基准代码
import random
import time
LEN = 1000000
class Thing():
def __init__(self, data):
self.data = data
def __repr__(self):
return 'thing{}'.format(self.data)
things = []
for n in range(LEN):
things.append(Thing(random.randrange(2,6)))
# minimum by looping
startminloop = time.time()
mindata = 99
for thing in things:
if thing.data<mindata:
mindata = thing.data
stopminloop = time.time()
# map for minimum
startmap = time.time()
mindata = min(map(lambda x: x.data, things))
stopmap = time.time()
# create list by looping
startlistloop = time.time()
outlist = []
for thing in things:
if thing.data==mindata:
outlist.append(thing)
stoplistloop = time.time()
# list comprehension
startcomp = time.time()
outlist = [x for x in things if x.data==mindata]
stopcomp = time.time()
# list by filter
startfilter = time.time()
outlist = list(filter(lambda x: x.data==mindata, things))
stopfilter = time.time()
# sort for minimum
startsort = time.time()
things.sort(key=lambda x: x.data)
stopsort = time.time()
我得到了以下结果
minimum finding
loop 0.07794857025146484
sort 0.22138357162475586
map 0.11729907989501953
list creation
loop 0.09957003593444824
comp 0.06798076629638672
filt 0.13345861434936523
我很惊讶地图和过滤器都比天真的循环方法慢得多。虽然它们的代码行数较少,但对于我的初学者而言,它们看起来并不那么清晰。我有兴趣看到列表理解胜过两种方法。
由于找到最小值的排序相当慢,我没有继续思考如何找到正确的位置来切割输出的排序列表,无论是二进制还是线性搜索,或索引是否可以被迫这样做。
这是使用地图和过滤器的错误位置吗? 我是正确地使用它们,还是我可以使用它们? 是否有更快的方法(无论如何在纯python中)执行此任务?