本文實(shí)例講述了Python中dictionary items()系列函數(shù)的用法,對Python程序設(shè)計(jì)有很好的參考借鑒價(jià)值。具體分析如下:
先來看一個(gè)示例:
import html # available only in Python 3.x def make_elements(name, value, **attrs): keyvals = [' %s="%s"' % item for item in attrs.items()] attr_str = ''.join(keyvals) element = '<{name}{attrs}>{value}'.format( name = name, attrs = attr_str, value = html.escape(value)) return element make_elements('item', 'Albatross', size='large', quantity=6) make_elements('p', '')
該程序的作用很簡單,就是生成HTML標(biāo)簽,注意html這個(gè)模塊只能在Python 3.x才有。
起初我只是注意到,生成標(biāo)簽屬性列表的keyvals這個(gè)dictionary類型變量構(gòu)建的方式很有意思,兩個(gè)%s對應(yīng)一個(gè)item,所以就查閱了相關(guān)的資料,結(jié)果扯出了挺多的東西,在此一并總結(jié)。
注:下面所有Python解釋器使用的版本,2.x 對應(yīng)的是2.7.3,3.x 對應(yīng)的是3.4.1
在 Python 2.x 里,官方文檔里items的方法是這么說明:生成一個(gè) (key, value) 對的list,就像下面這樣:
>>> d = {'size': 'large', 'quantity': 6} >>> d.items() [('quantity', 6), ('size', 'large')]
在搜索的過程中,無意看到stackoverflow上這樣一個(gè)問題:dict.items()和dict.iteritems()有什么區(qū)別? ,第一個(gè)答案大致的意思是這樣的:
“起初 items() 就是返回一個(gè)像上面那樣的包含dict所有元素的list,但是由于這樣太浪費(fèi)內(nèi)存,所以后來就加入了(注:在Python 2.2開始出現(xiàn)的)iteritems(), iterkeys(), itervalues()這一組函數(shù),用于返回一個(gè) iterator 來節(jié)省內(nèi)存,但是在 3.x 里items() 本身就返回這樣的 iterator,所以在 3.x 里items() 的行為和 2.x 的 iteritems() 行為一致,iteritems()這一組函數(shù)就廢除了。”
不過更加有意思的是,這個(gè)答案雖然被采納,下面的評論卻指出,這種說法并不準(zhǔn)確,在 3.x 里 items() 的行為和 2.x 的 iteritems() 不一樣,它實(shí)際上返回的是一個(gè)"full sequence-protocol object",這個(gè)對象能夠反映出 dict 的變化,后來在 Python 2.7 里面也加入了另外一個(gè)函數(shù) viewitems() 和 3.x 的這種行為保持一致
為了證實(shí)評論中的說法,我做了下面的測試,注意觀察測試中使用的Python版本:
測試1(Python 2.7.3):
Python 2.7.3 (default, Feb 27 2014, 19:58:35) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> d = {'size': 'large', 'quantity': 6} >>> il = d.items() >>> it = d.iteritems() >>> vi = d.viewitems() >>> il [('quantity', 6), ('size', 'large')] >>> it>>> vi dict_items([('quantity', 6), ('size', 'large')])
測試2(Python 3.4.1):
Python 3.4.1 (default, Aug 12 2014, 16:43:01) [GCC 4.9.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> d = {'size': 'large', 'quantity': 6} >>> il = d.items() >>> it = d.iteritems() Traceback (most recent call last): File "", line 1, in AttributeError: 'dict' object has no attribute 'iteritems' >>> vi = d.viewitems() Traceback (most recent call last): File " ", line 1, in AttributeError: 'dict' object has no attribute 'viewitems' >>> il dict_items([('size', 'large'), ('quantity', 6)])
可以看到在 Python 3.x 里面,iteritems() 和 viewitems() 這兩個(gè)方法都已經(jīng)廢除了,而 item() 得到的結(jié)果是和 2.x 里面 viewitems() 一致的。
2.x 里 iteritems() 和 viewitems() 返回的內(nèi)容都是可以用 for 來遍歷的,像下面這樣
>>> for k, v in it: ... print k, v ... quantity 6 size large >>> for k, v in vi: ... print k, v ... quantity 6 size large
這兩者的區(qū)別體現(xiàn)在哪里呢?viewitems() 返回的是view object,它可以反映出 dictionary 的變化,比如上面的例子,假如在使用 it 和 vi 這兩個(gè)變量之前,向 d 里面添加一個(gè)key-value組合,區(qū)別就很容易看出來了。
>>> it = d.iteritems() >>> vi = d.viewitems() >>> d['newkey'] = 'newvalue' >>> d {'newkey': 'newvalue', 'quantity': 6, 'size': 'large'} >>> vi dict_items([('newkey', 'newvalue'), ('quantity', 6), ('size', 'large')]) >>> it>>> for k, v in vi: ... print k, v ... newkey newvalue quantity 6 size large >>> for k, v in it: ... print k, v ... Traceback (most recent call last): File " ", line 1, in RuntimeError: dictionary changed size during iteration
在第三行中,我們像 d 里面插入了一個(gè)新的元素,vi 可以繼續(xù)遍歷,而且新的遍歷能夠反映出 d 的變化,但是在遍歷 it 的時(shí)候,報(bào)錯(cuò)提示 dictionary 在遍歷的時(shí)候大小發(fā)生了變化,遍歷失敗。
總結(jié)起來,在 2.x 里面,最初是 items() 這個(gè)方法,但是由于太浪費(fèi)內(nèi)存,所以加入了 iteritems() 方法,用于返回一個(gè) iterator,在 3.x 里面將 items() 的行為修改成返回一個(gè) view object,讓它返回的對象同樣也可以反映出原 dictionary 的變化,同時(shí)在 2.7 里面又加入了 viewitems() 向下兼容這個(gè)特性。
所以在 3.x 里面不需要再去糾結(jié)于三者的不同之處,因?yàn)橹槐A袅艘粋€(gè) items() 方法。
相信本文所述示例對大家的Python程序設(shè)計(jì)有一定的借鑒價(jià)值。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
