zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Python中dictionaryitems()系列函数的用法实例

Python实例 函数 用法 系列
2023-06-13 09:15:43 时间

本文实例讲述了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程序设计有一定的借鉴价值。