前言:對於我這種追求極致的人來說,效率很重要。
前面看到網上關於python循環的測評,到自己在項目中的應用,發現,並不是這么回事。所以,寫下次博文,一次性了解這個問題。
語言版本:python3.6
平台:mac10.12.6
IDE:pycharm community 2018.2
關於循環的介紹:
1. for循環
我們最開始使用的循環。for循環的對象是可迭代對象。這里不詳述。
2. 列表解析式
與之類似,字典解析式,集合解析式等。
3. map循環
與之類似有reduce,filter。這里不詳述。
最終測試結果:
map比列表解析式快一點點,
列表解析式,大概比普通for循環快1.5倍。
符合預期。(擦了一把汗!)
ps:有同學測試,說map速度遠遠大與列表推導式(大概快10000倍),這是因為他返回的是生成器對象,並沒有計算出結果,所以這個不算。
以上測試,只是反映實際情況一種。並不能說這個是公理。僅僅給大家提供參考。博主不才。
測試開始:
import time i = list(range(1000000)) # 生成測試序列
首先測試將數字轉換成字符串:
i = list(range(1000000))
t = time.time()
lt_1 = []
for each in i:
lt_1.append(str(each))
t2 = time.time()
print(t2 - t)
lt_2 = [lambda x: str(x) for x in i]
t3 = time.time()
print(t3 - t2)
lt_3 = list(map(lambda x: str(x), i))
t4 = time.time()
print(t4 - t3)
結果:
0.5911688804626465
1.0817310810089111
0.7083189487457275
0.4922349452972412
1.0927751064300537
0.4922208786010742
0.5165529251098633
1.100153923034668
0.5037112236022949
結果很意外,對吧,直接采用for循環,效率比列表解析式高一倍。和網絡上的教程有出入。
說明:python3 map返回的是生成器(python2 map返回列表),需要使用list來驅動他得出結果。
接下來測試計算:
i = list(range(1000000))
t = time.time()
lt_1 = [] for each in i: each += 1 lt_1.append(each) t2 = time.time() print(t2 - t) lt_2 = [lambda x: x+1 for x in i] t3 = time.time() print(t3 - t2) lt_3 = list(map(lambda x: x+1, i)) t4 = time.time() print(t4 - t3)
結果:
0.349423885345459
1.0195939540863037
0.21120715141296387
0.4159379005432129
1.1701478958129883
0.21973800659179688
0.32332897186279297
1.2796630859375
0.36236000061035156
這里能看到,map顯著比for循環高,for循環比列表解析式快,這個貌似還是有些出入。
ps:對每次結果不同的解釋:由於系統本身還在運行其他程序。所以,在調用python時,不可避免需要等待其他程序結束。所以會出現第三次結果的情況。
我測試了很多遍,基本結論是,map比for循環大概快1.5倍。
但是,當我把結果打印出來時,發現,列表解析式內使用lamba,返回的是<function <listcomp>.<lambda> at 0x10e154510>,不會直接返回值:所以,更新下測試代碼。
# ------------------------------- i = list(range(1000000)) t = time.time() lt_1 = [] for each in i: each += 1 lt_1.append(each) t2 = time.time() print(t2 - t) def ggwp(x): return x+1 lt_2 = [ggwp(x) for x in i] t3 = time.time() print(t3 - t2) lt_3 = list(map(lambda x: x+1, i)) t4 = time.time() print(t4 - t3)
結果:
0.32393980026245117
0.2332770824432373
0.2076709270477295
0.3169240951538086
0.23195600509643555
0.20856499671936035
0.2955038547515869
0.23477792739868164
0.20820212364196777
所以,最終結果是:map速度最快,其次是列表解析式,最后是for循環。
同樣更新第一個實驗的測試代碼:
i = list(range(1000000)) t = time.time() lt_1 = [] for each in i: lt_1.append(str(each)) t2 = time.time() # print(lt_1) print(t2 - t) def ggwp(x): return str(x) lt_2 = [ggwp for x in i] t3 = time.time() # print(lt_2) print(t3 - t2) lt_3 = list(map(lambda x: str(x), i)) t4 = time.time() # print(lt_3) print(t4 - t3)
0.5370810031890869
0.08401012420654297
0.5191819667816162
發現,這個列表解析式,效率明顯高於其他2個。於是,再次修改代碼。
import time
# -------------------------------
i = list(range(1000000))
t = time.time()
lt_1 = []
for each in i:
lt_1.append(str(each))
t2 = time.time()
# print(lt_1)
print(t2 - t)
def ggwp(x):
return str(x)
lt_2 = [ggwp for x in i]
t3 = time.time()
# print(lt_2)
print(t3 - t2)
# lt_3 = list(map(lambda x: str(x), i))
lt_3 = list(map(ggwp, i))
t4 = time.time()
# print(lt_3)
print(t4 - t3)
0.480226993560791
0.06554508209228516
0.5108628273010254
是不是很神奇?WHY?為什么列表解析式的效率一下子提高這么多?
找到原因,因為紅色的ggwp,只寫了函數名。和之前的lambda類似,<function ggwp at 0x10e255488>。這個不符合要求。
修正后:
lt_2 = [ggwp(x) for x in i]
0.4904050827026367
0.5147149562835693
0.49653005599975586
0.5053339004516602
0.502392053604126
0.49272894859313965
0.49378418922424316
0.4825170040130615
0.5087540149688721
發現,速度差不多。基本相同。
再來測試乘法運算:
i = list(range(1000000))
t = time.time()
lt_1 = []
for each in i:
each = each*each
lt_1.append(each)
# print(lt_1)
t2 = time.time()
print(t2 - t)
def ggwp(x):
return x*x
lt_2 = [ggwp(x) for x in i]
# print(lt_2)
t3 = time.time()
print(t3 - t2)
lt_3 = list(map(lambda x: x*x, i))
# print(lt_3)
t4 = time.time()
print(t4 - t3)
0.5563499927520752
0.3827509880065918
0.3217048645019531
0.3309590816497803
0.21875500679016113
0.2042989730834961
0.3309590816497803
0.21875500679016113
0.2042989730834961
結果:map總體比列表解析式快一點。列表解析式大概比for循環快1.5倍。
----------------------------------------------------------------