python 字典和列表的讀取速度問題
最近在進行基因組數據處理的時候,需要讀取較大數據(2.7G)存入字典中,然后對被處理數據進行字典key值的匹配,在被處理文件中每次讀取一行進行處理后查找是否在字典的keys中,以下兩段代碼的效率差別非常大:
第一段:
if(pos in fre_dist.keys()):
newvalue= fre_dist[pos]
第二段:
if(pos in fre_dist):
newValue=fre_dist[pos]
在處理3萬條數據時,第二段代碼的速度是第一段代碼速度的上千倍。
原因是:第一段代碼 fre_dist.keys()變成了list,python在檢索list的時候是比較慢的,第二段代碼 fre_dist是字典,python在檢索字典的時候速度是比較快的。
血的教訓。
dict結構,我想大多數人都會想到 for key in dictobj 的方法,確實這個方法在大多數情況下都是適用的。但是並不是完全安全,請看下面這個例子:
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#本意是遍歷dict,發現元素的值是0的話,就刪掉
>>> for k in d:
... if d[k] == 0:
... del(d[k])
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
#結果拋出異常了,兩個0的元素,也只刪掉一個。
>>> d
{'a': 1, 'c': 1, 'd': 0}
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys() 是一個下標的數組
>>> d.keys()
['a', 'c', 'b', 'd']
#這樣遍歷,就沒問題了,因為其實其實這里遍歷的是d.keys()這個list常量。
>>> for k in d.keys():
... if d[k] == 0:
... del(d[k])
...
>>> d
{'a': 1, 'c': 1}
#結果也是對的
>>>
其實,這個例子是我簡化過的,我是在一個多線程的程序里發現這個問題的,所以,我的建議是:遍歷dict的時候,養成使用 for k in d.keys() 的習慣。
不過,如果是多線程的話,這樣就絕對安全嗎?也不見得:當兩個線程都取完d.keys()以后,如果兩個線程都去刪同一個key的話,先刪的會成功,后刪的那個肯定會報 KeyError ,這個看來只能通過其他方式來保證了。
另一篇:dict 兩種遍歷方式的性能對比
關於糾結dict遍歷中帶括號與不帶括號的性能問題
for (d,x) in dict.items():
print "key:"+d+",value:"+str(x)
for d,x in dict.items():
print "key:"+d+",value:"+str(x)
我們可以看出,dict條數在200一下的時候是帶括號的性能比較高一點,但是在200條以上的數據后不帶括號的執行時間會少些.
字典用花括號({})表示,里面的項成對出現,一個 key 對應一個 value;key 與 value
之間用冒號(:)分隔;不同的項之間用逗號(,)分隔。
Python Shell:
n = {'username':'zz',"password":123} n.keys() dict_keys(['username', 'password']) n.values() dict_keys(['zz', 123]) n.items() dict_items([('username', 'zc'), ('password', 123)]) for (k,v) in n.items(): print("this's key:%r" %k) print("this's value:%r" %v") this's key:'username' this's value:'zc' this's key:'password' this's value:123
zip():就是依次取出每一個數組的元素,然后組合
n = [1,2,3] m = ['a','b','c'] a = zip(m,n) for i in a: print(i) ('a', 1) ('b', 2) ('c', 3)
n = [1,2,3] m = ['a','b','c'] a = zip(m,n) for (m,n) in a: print(m,n) a 1 b 2 c 3
range合並:
for i in range(48,58)+range(65,91):
c8=chr(i);