Python中dictionary items()系列函数的用法实例
本文实例讲述了Python中dictionaryitems()系列函数的用法,对Python程序设计有很好的参考借鉴价值。具体分析如下:
先来看一个示例:
importhtml#availableonlyinPython3.x defmake_elements(name,value,**attrs): keyvals=['%s="%s"'%itemforiteminattrs.items()] attr_str=''.join(keyvals) element='<{name}{attrs}>{value}</{name}>'.format( name=name, attrs=attr_str, value=html.escape(value)) returnelement make_elements('item','Albatross',size='large',quantity=6) make_elements('p','<spam>')
该程序的作用很简单,就是生成HTML标签,注意html这个模块只能在Python3.x才有。
起初我只是注意到,生成标签属性列表的keyvals这个dictionary类型变量构建的方式很有意思,两个%s对应一个item,所以就查阅了相关的资料,结果扯出了挺多的东西,在此一并总结。
注:下面所有Python解释器使用的版本,2.x对应的是2.7.3,3.x对应的是3.4.1
在Python2.x里,官方文档里items的方法是这么说明:生成一个(key,value)对的list,就像下面这样:
>>>d={'size':'large','quantity':6} >>>d.items() [('quantity',6),('size','large')]
在搜索的过程中,无意看到stackoverflow上这样一个问题:dict.items()和dict.iteritems()有什么区别?,第一个答案大致的意思是这样的:
“起初items()就是返回一个像上面那样的包含dict所有元素的list,但是由于这样太浪费内存,所以后来就加入了(注:在Python2.2开始出现的)iteritems(),iterkeys(),itervalues()这一组函数,用于返回一个iterator来节省内存,但是在3.x里items()本身就返回这样的iterator,所以在3.x里items()的行为和2.x的iteritems()行为一致,iteritems()这一组函数就废除了。”
不过更加有意思的是,这个答案虽然被采纳,下面的评论却指出,这种说法并不准确,在3.x里items()的行为和2.x的iteritems()不一样,它实际上返回的是一个"fullsequence-protocolobject",这个对象能够反映出dict的变化,后来在Python2.7里面也加入了另外一个函数viewitems()和3.x的这种行为保持一致
为了证实评论中的说法,我做了下面的测试,注意观察测试中使用的Python版本:
测试1(Python2.7.3):
Python2.7.3(default,Feb272014,19:58:35) [GCC4.6.3]onlinux2 Type"help","copyright","credits"or"license"formoreinformation. >>>d={'size':'large','quantity':6} >>>il=d.items() >>>it=d.iteritems() >>>vi=d.viewitems() >>>il [('quantity',6),('size','large')] >>>it <dictionary-itemiteratorobjectat0x7fe555159f18> >>>vi dict_items([('quantity',6),('size','large')])
测试2(Python3.4.1):
Python3.4.1(default,Aug122014,16:43:01) [GCC4.9.0]onlinux Type"help","copyright","credits"or"license"formoreinformation. >>>d={'size':'large','quantity':6} >>>il=d.items() >>>it=d.iteritems() Traceback(mostrecentcalllast): File"<stdin>",line1,in<module> AttributeError:'dict'objecthasnoattribute'iteritems' >>>vi=d.viewitems() Traceback(mostrecentcalllast): File"<stdin>",line1,in<module> AttributeError:'dict'objecthasnoattribute'viewitems' >>>il dict_items([('size','large'),('quantity',6)])
可以看到在Python3.x里面,iteritems()和viewitems()这两个方法都已经废除了,而item()得到的结果是和2.x里面viewitems()一致的。
2.x里iteritems()和viewitems()返回的内容都是可以用for来遍历的,像下面这样
>>>fork,vinit: ...printk,v ... quantity6 sizelarge >>>fork,vinvi: ...printk,v ... quantity6 sizelarge
这两者的区别体现在哪里呢?viewitems()返回的是viewobject,它可以反映出dictionary的变化,比如上面的例子,假如在使用it和vi这两个变量之前,向d里面添加一个key-value组合,区别就很容易看出来了。
>>>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 <dictionary-itemiteratorobjectat0x7f50ab898f70> >>>fork,vinvi: ...printk,v ... newkeynewvalue quantity6 sizelarge >>>fork,vinit: ...printk,v ... Traceback(mostrecentcalllast): File"<stdin>",line1,in<module> RuntimeError:dictionarychangedsizeduringiteration
在第三行中,我们像d里面插入了一个新的元素,vi可以继续遍历,而且新的遍历能够反映出d的变化,但是在遍历it的时候,报错提示dictionary在遍历的时候大小发生了变化,遍历失败。
总结起来,在2.x里面,最初是items()这个方法,但是由于太浪费内存,所以加入了iteritems()方法,用于返回一个iterator,在3.x里面将items()的行为修改成返回一个viewobject,让它返回的对象同样也可以反映出原dictionary的变化,同时在2.7里面又加入了viewitems()向下兼容这个特性。
所以在3.x里面不需要再去纠结于三者的不同之处,因为只保留了一个items()方法。
相信本文所述示例对大家的Python程序设计有一定的借鉴价值。