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


Posted in Python onAugust 21, 2014

本文实例讲述了Python中dictionary items()系列函数的用法,对Python程序设计有很好的参考借鉴价值。具体分析如下:

先来看一个示例:

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}</{name}>'.format( 
      name = name, 
      attrs = attr_str, 
      value = html.escape(value)) 
  return element 
make_elements('item', 'Albatross', size='large', quantity=6) 
make_elements('p', '<spam>')

该程序的作用很简单,就是生成HTML标签,注意html这个模块只能在Python 3.x才有。

起初我只是注意到,生成标签属性列表的keyvals这个dictionary类型变量构建的方式很有意思,两个%s对应一个item,所以就查阅了相关的资料,结果扯出了挺多的东西,在此一并总结。

注:下面所有Python解释器使用的版本,2.x 对应的是2.7.3,3.x 对应的是3.4.1
在 Python 2.x 里,官方文档里items的方法是这么说明:生成一个 (key, value) 对的list,就像下面这样:

>>> d = {'size': 'large', 'quantity': 6} 
>>> d.items() 
[('quantity', 6), ('size', 'large')]

在搜索的过程中,无意看到stackoverflow上这样一个问题:dict.items()和dict.iteritems()有什么区别? ,第一个答案大致的意思是这样的:

“起初 items() 就是返回一个像上面那样的包含dict所有元素的list,但是由于这样太浪费内存,所以后来就加入了(注:在Python 2.2开始出现的)iteritems(), iterkeys(), itervalues()这一组函数,用于返回一个 iterator 来节省内存,但是在 3.x 里items() 本身就返回这样的 iterator,所以在 3.x 里items() 的行为和 2.x 的 iteritems() 行为一致,iteritems()这一组函数就废除了。”

不过更加有意思的是,这个答案虽然被采纳,下面的评论却指出,这种说法并不准确,在 3.x 里 items() 的行为和 2.x 的 iteritems() 不一样,它实际上返回的是一个"full sequence-protocol object",这个对象能够反映出 dict 的变化,后来在 Python 2.7 里面也加入了另外一个函数 viewitems() 和 3.x 的这种行为保持一致
为了证实评论中的说法,我做了下面的测试,注意观察测试中使用的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 
<dictionary-itemiterator object at 0x7fe555159f18> 
>>> 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 "<stdin>", line 1, in <module> 
AttributeError: 'dict' object has no attribute 'iteritems' 
>>> vi = d.viewitems() 
Traceback (most recent call last): 
 File "<stdin>", line 1, in <module> 
AttributeError: 'dict' object has no attribute 'viewitems' 
>>> il 
dict_items([('size', 'large'), ('quantity', 6)])

可以看到在 Python 3.x 里面,iteritems() 和 viewitems() 这两个方法都已经废除了,而 item() 得到的结果是和 2.x 里面 viewitems() 一致的。
2.x 里 iteritems() 和 viewitems() 返回的内容都是可以用 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

这两者的区别体现在哪里呢?viewitems() 返回的是view object,它可以反映出 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-itemiterator object at 0x7f50ab898f70> 
>>> 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 "<stdin>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration

在第三行中,我们像 d 里面插入了一个新的元素,vi 可以继续遍历,而且新的遍历能够反映出 d 的变化,但是在遍历 it 的时候,报错提示 dictionary 在遍历的时候大小发生了变化,遍历失败。

总结起来,在 2.x 里面,最初是 items() 这个方法,但是由于太浪费内存,所以加入了 iteritems() 方法,用于返回一个 iterator,在 3.x 里面将 items() 的行为修改成返回一个 view object,让它返回的对象同样也可以反映出原 dictionary 的变化,同时在 2.7 里面又加入了 viewitems() 向下兼容这个特性。
所以在 3.x 里面不需要再去纠结于三者的不同之处,因为只保留了一个 items() 方法。

相信本文所述示例对大家的Python程序设计有一定的借鉴价值。

Python 相关文章推荐
使用PyCharm配合部署Python的Django框架的配置纪实
Nov 19 Python
朴素贝叶斯分类算法原理与Python实现与使用方法案例
Jun 26 Python
对python Tkinter Text的用法详解
Oct 11 Python
学生信息管理系统Python面向对象版
Jan 30 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
Aug 12 Python
用Python将Excel数据导入到SQL Server的例子
Aug 24 Python
结合OpenCV与TensorFlow进行人脸识别的实现
Oct 10 Python
利用Tensorflow构建和训练自己的CNN来做简单的验证码识别方式
Jan 20 Python
python ffmpeg任意提取视频帧的方法
Feb 21 Python
浅谈在django中使用filter()(即对QuerySet操作)时踩的坑
Mar 31 Python
pycharm中使用request和Pytest进行接口测试的方法
Jul 31 Python
Python操作CSV格式文件的方法大全
Jul 15 Python
Python 不同对象比较大小示例探讨
Aug 21 #Python
python字符串连接方式汇总
Aug 21 #Python
零基础学Python(一)Python环境安装
Aug 20 #Python
Python中replace方法实例分析
Aug 20 #Python
Python内置的字符串处理函数详细整理(覆盖日常所用)
Aug 19 #Python
Python中列表(list)操作方法汇总
Aug 18 #Python
Python中多线程thread与threading的实现方法
Aug 18 #Python
You might like
PHP新手上路(十二)
2006/10/09 PHP
排序算法之PHP版快速排序、冒泡排序
2014/04/09 PHP
php实现兼容2038年后Unix时间戳转换函数
2015/03/18 PHP
PHP简单预防sql注入的方法
2016/09/27 PHP
thinkphp5框架实现的自定义扩展类操作示例
2019/05/16 PHP
js函数般调用正则
2008/04/08 Javascript
ext for eclipse插件安装方法
2008/04/27 Javascript
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
ExtJs的Date格式字符代码
2010/12/30 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
用js设置下拉框为只读的小技巧
2014/04/10 Javascript
Js保留小数点的4种效果实现代码分享
2014/04/12 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
JavaScript中的Array 对象(数组对象)
2016/06/02 Javascript
利用BootStrap的Carousel.js实现轮播图动画效果
2016/12/21 Javascript
vue-router 源码实现前端路由的两种方式
2018/07/02 Javascript
微信小程序 Animation实现图片旋转动画示例
2018/08/22 Javascript
AngularJS $http post 传递参数数据的方法
2018/10/09 Javascript
微信小程序实现带缩略图轮播效果
2018/11/04 Javascript
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
讲解python参数和作用域的使用
2013/11/01 Python
更改Ubuntu默认python版本的两种方法python-&gt; Anaconda
2016/12/18 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
Python的numpy库中将矩阵转换为列表等函数的方法
2018/04/04 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
行政总经理岗位职责
2013/12/05 职场文书
蜜蜂引路教学反思
2014/02/04 职场文书
小学生倡议书范文
2014/05/13 职场文书
税务职业生涯规划书范文
2014/09/16 职场文书
领导干部个人对照检查材料(群众路线)
2014/09/26 职场文书
基层党支部整改方案
2014/10/25 职场文书
2014年反腐倡廉工作总结
2014/12/05 职场文书
大学生操行评语大全
2014/12/31 职场文书
我的法兰西岁月观后感
2015/06/09 职场文书
大学生就业指导课心得体会
2016/01/15 职场文书