在回答問題Clunky calculation of differences between an incrementing set of numbers, is there a more beautiful way?時,我想出了兩個解決方案,一個使用List Comprehension
,另一個使用itertools.starmap
。當`starmap`優先於`List Comprehension`時
對我來說,list comprehension
語法看起來更清晰,更易讀,更簡潔且更具Pythonic。但仍然starmap
在itertools中可用,我想知道,它必須有一個原因。
我的問題是當starmap
可能優於List Comprehension
?
注意如果其風格的問題,然後它絕對違背There should be one-- and preferably only one --obvious way to do it.
頭對頭比較
可讀性計數。 --- LC
它再次是一個知覺問題,但對我來說LC
比starmap
更具可讀性。 要使用starmap
,要麼需要導入operator
,要麼定義lambda
或某種明確的multi-variable
函數,但仍需從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',因爲目前''use_star_map'由於它全部在一行中而不易讀。改爲:'deltas = starmap(sub,zip(nums [1:],nums))'sum(deltas)/ float(len(nums)-1)' – jamylak
@jamylak:謝謝你指出。但不幸的是,它不會改變性能差異。 – Abhijit
這不是我們的意思,但我們也在談論可讀性。 – jamylak