在回答问题 Clunky calculation of differences between an incrementing set of numbers, is there a more beautiful way?时,我想出了两种解决方案,一种是使用List Comprehension
,另一种是使用 itertools.starmap。
对我来说,list comprehension
的语法更加清晰、易读、简洁且更符合Python风格。但是既然 starmap在itertools中已经很常见了,我想知道它肯定有其存在的原因。
我的问题是,何时应该优先使用starmap
而不是List Comprehension
?
注意:如果这只是一个风格问题,那么它肯定与“做一件事应该有一种——最好只有一种——明显的方法。”相矛盾。
头对头比较
易读性很重要。 --- LC
虽然这是个主观的问题,但对我来说,LC
比 starmap
更易读。
要使用 starmap
,你需要导入 operator
,或定义 lambda
或一些显式的 多变量
函数,并且额外导入 itertools
。
性能 --- LC
>>> def using_star_map(nums):
delta=starmap(sub,izip(nums[1:],nums))
return sum(delta)/float(len(nums)-1)
>>> def using_LC(nums):
delta=(x-y for x,y in izip(nums[1:],nums))
return sum(delta)/float(len(nums)-1)
>>> nums=[random.randint(1,10) for _ in range(100000)]
>>> t1=Timer(stmt='using_star_map(nums)',setup='from __main__ import nums,using_star_map;from itertools import starmap,izip')
>>> t2=Timer(stmt='using_LC(nums)',setup='from __main__ import nums,using_LC;from itertools import izip')
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=1000)/100000)
235.03 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=1000)/100000)
181.87 usec/pass
deltas
中,因为此时using_star_map
函数的可读性较低,因为它全部在一行中呈现。请将其更改为:deltas = starmap(sub,zip(nums[1:],nums))
sum(deltas)/float(len(nums)-1)
。 - jamylak