python兩種遍歷字典(dict)的方法比較
python以其優(yōu)美的語(yǔ)法和方便的內(nèi)置數(shù)據(jù)結(jié)構(gòu),贏得了不少程序員的親睞。
其中有個(gè)很有用的數(shù)據(jù)結(jié)構(gòu),就是字典(dict),使用非常簡(jiǎn)單。說(shuō)到遍歷一個(gè)dict結(jié)構(gòu),我想大多數(shù)人都會(huì)想到 for key in dictobj 的方法,確實(shí)這個(gè)方法在大多數(shù)情況下都是適用的。但是并不是完全安全,請(qǐng)看下面這個(gè)例子:
#這里初始化一個(gè)dict
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#本意是遍歷dict,發(fā)現(xiàn)元素的值是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
#結(jié)果拋出異常了,兩個(gè)0的元素,也只刪掉一個(gè)。
>>> d
{'a': 1, 'c': 1, 'd': 0}
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys() 是一個(gè)下標(biāo)的數(shù)組
>>> d.keys()
['a', 'c', 'b', 'd']
#這樣遍歷,就沒(méi)問(wèn)題了,因?yàn)槠鋵?shí)其實(shí)這里遍歷的是d.keys()這個(gè)list常量。
>>> for k in d.keys():
... if d[k] == 0:
... del(d[k])
...
>>> d
{'a': 1, 'c': 1}
#結(jié)果也是對(duì)的
>>>
其實(shí),這個(gè)例子是我簡(jiǎn)化過(guò)的,我是在一個(gè)多線程的程序里發(fā)現(xiàn)這個(gè)問(wèn)題的,所以,我的建議是:遍歷dict的時(shí)候,養(yǎng)成使用 for k in d.keys() 的習(xí)慣。
不過(guò),如果是多線程的話,這樣就絕對(duì)安全嗎?也不見(jiàn)得:當(dāng)兩個(gè)線程都取完d.keys()以后,如果兩個(gè)線程都去刪同一個(gè)key的話,先刪的會(huì)成功,后刪的那個(gè)肯定會(huì)報(bào) KeyError ,這個(gè)看來(lái)只能通過(guò)其他方式來(lái)保證了。
另一篇:dict 兩種遍歷方式的性能對(duì)比
關(guān)于糾結(jié)dict遍歷中帶括號(hào)與不帶括號(hào)的性能問(wèn)題
for (d,x) in dict.items():
print "key:"+d+",value:"+str(x)
for d,x in dict.items():
print "key:"+d+",value:"+str(x)
帶括號(hào)和不帶括號(hào)性能測(cè)試結(jié)果:
測(cè)試結(jié)果
測(cè)試條數(shù):15
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:13:37.375000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:13:37.375000
時(shí)間間隔:0:00:00
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:13:37.375000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:13:37.375000
時(shí)間間隔:0:00:00
測(cè)試條數(shù):50
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:13:57.921000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:13:57.921000
時(shí)間間隔:0:00:00
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:13:57.921000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:13:57.937000
時(shí)間間隔:0:00:00.016000
測(cè)試條數(shù):100
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:53:57.453000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:53:57.468000
時(shí)間間隔:0:00:00.015000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:53:57.468000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:53:57.531000
時(shí)間間隔:0:00:00.063000
測(cè)試條數(shù):150
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:00:54.812000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:00:54.828000
時(shí)間間隔:0:00:00.016000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:00:54.828000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:00:54.921000
時(shí)間間隔:0:00:00.093000
測(cè)試條數(shù):200
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:59:54.609000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:59:54.687000
時(shí)間間隔:0:00:00.078000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:59:54.687000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:59:54.734000
時(shí)間間隔:0:00:00.047000
測(cè)試條數(shù):500
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:39.906000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:40.078000
時(shí)間間隔:0:00:00.172000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:40.078000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:40.125000
時(shí)間間隔:0:00:00.047000
測(cè)試條數(shù):1000
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:49.171000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:49.437000
時(shí)間間隔:0:00:00.266000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:49.437000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:49.609000
時(shí)間間隔:0:00:00.172000
測(cè)試條數(shù):2000
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:58.921000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:59.328000
時(shí)間間隔:0:00:00.407000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:54:59.328000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:54:59.687000
時(shí)間間隔:0:00:00.359000
測(cè)試條數(shù):5000
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:55:05.781000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:55:06.734000
時(shí)間間隔:0:00:00.953000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:55:06.734000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:55:07.609000
時(shí)間間隔:0:00:00.875000
測(cè)試條數(shù):10000
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:55:15.656000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:55:17.390000
時(shí)間間隔:0:00:01.734000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 11:55:17.390000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 11:55:19.109000
時(shí)間間隔:0:00:01.719000
測(cè)試條數(shù):20000
帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:19:14.921000
帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:19:18.593000
時(shí)間間隔:0:00:03.672000
不帶括號(hào)開(kāi)始時(shí)間:2012-06-14 12:19:18.593000
不帶括號(hào)結(jié)束時(shí)間:2012-06-14 12:19:22.218000
時(shí)間間隔:0:00:03.625000
我們可以看出,dict條數(shù)在200一下的時(shí)候是帶括號(hào)的性能比較高一點(diǎn),但是在200條以上的數(shù)據(jù)后不帶括號(hào)的執(zhí)行時(shí)間會(huì)少些.
下面是測(cè)試代碼:
測(cè)試Code
#-*- coding: utf-8 -*-
import datetime,codecs
dict = {}
for i in xrange(0,20000):
dict.setdefault("name"+str(i))
dict["name"+str(i)]="name"
s=codecs.open(r'c:\\dict.txt','a', 'utf-8')
def write(des):
s.write(des.decode("utf-8"))
write("測(cè)試條數(shù):")
write(str(len(dict))+"\r\n")
write("帶括號(hào)開(kāi)始時(shí)間:")
a=datetime.datetime.now()
s.write(str(a)+"\r\n")
for (d,x) in dict.items():
print "key:"+d+",value:"+str(x)
write("帶括號(hào)結(jié)束時(shí)間:")
b=datetime.datetime.now()
write(str(b)+"\r\n")
write("時(shí)間間隔:")
write(str(b-a)+"\r\n")
write("不帶括號(hào)開(kāi)始時(shí)間:")
c=datetime.datetime.now()
write(str(c)+"\r\n")
for d,x in dict.items():
print "key:"+d+",value:"+str(x)
write("不帶括號(hào)結(jié)束時(shí)間:")
d=datetime.datetime.now()
write(str(d)+"\r\n")
write("時(shí)間間隔:")
write(str(d-c)+"\r\n")
write("\r\n")
s.close()
中文亂碼問(wèn)題有沒(méi)有很好的解決辦法....?
相關(guān)文章
Python利用Flask-Mail實(shí)現(xiàn)發(fā)送郵件詳解
Flask?的擴(kuò)展包?Flask?-?Mail?通過(guò)包裝了?Python?內(nèi)置的smtplib包,可以用在?Flask?程序中發(fā)送郵件。本文將利用這特性實(shí)現(xiàn)郵件發(fā)送功能,感興趣的可以了解一下2022-08-08pytorch/transformers?最后一層不加激活函數(shù)的原因分析
這里給大家解釋一下為什么bert模型最后都不加激活函數(shù),是因?yàn)閾p失函數(shù)選擇的原因,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-01-01python學(xué)生管理系統(tǒng)代碼實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了python學(xué)生管理系統(tǒng)代碼實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03分布式訓(xùn)練training-operator和pytorch-distributed?RANK變量不統(tǒng)一解決
這篇文章主要介紹了分布式訓(xùn)練training-operator和pytorch-distributed?RANK變量不統(tǒng)一問(wèn)題的解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04