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 相关文章推荐
python利用elaphe制作二维条形码实现代码
May 25 Python
python中的lambda表达式用法详解
Jun 22 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
Python获取二维矩阵每列最大值的方法
Apr 03 Python
Python嵌套列表转一维的方法(压平嵌套列表)
Jul 03 Python
python中的单引号双引号区别知识点总结
Jun 23 Python
使用Python代码实现Linux中的ls遍历目录命令的实例代码
Sep 07 Python
pygame库实现俄罗斯方块小游戏
Oct 29 Python
From CSV to SQLite3 by python 导入csv到sqlite实例
Feb 14 Python
pycharm下pyqt4安装及环境配置的教程
Apr 24 Python
简单的命令查看安装的python版本号
Aug 28 Python
Pytorch使用shuffle打乱数据的操作
May 20 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 CKEditor 上传图片实现代码
2009/11/06 PHP
基于curl数据采集之单页面并行采集函数get_htmls的使用
2013/04/28 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
PHP依赖注入(DI)和控制反转(IoC)详解
2017/06/12 PHP
php递归函数怎么用才有效
2018/02/24 PHP
PHP实现非阻塞模式的方法分析
2018/07/26 PHP
取得一定长度的内容,处理中文
2006/12/20 Javascript
javascript 自动转到命名锚记
2009/01/10 Javascript
理解JavaScript原型链
2016/10/25 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
vue-router的HTML5 History 模式设置
2018/09/08 Javascript
vue 使用localstorage实现面包屑的操作
2020/11/16 Javascript
[06:53]DOTA2每周TOP10 精彩击杀集锦vol.3
2014/06/25 DOTA
详谈Python基础之内置函数和递归
2017/06/21 Python
python+opencv实现高斯平滑滤波
2020/07/21 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
2019/08/12 Python
python 实现多线程下载m3u8格式视频并使用fmmpeg合并
2019/11/15 Python
python模拟实现斗地主发牌
2020/01/07 Python
tensorflow自定义激活函数实例
2020/02/04 Python
python如何实现复制目录到指定目录
2020/02/13 Python
Python基于pip实现离线打包过程详解
2020/05/15 Python
Python迭代器协议及for循环工作机制详解
2020/07/14 Python
2分钟教你实现环形/扇形菜单(基础版)
2020/01/15 HTML / CSS
英国的屈臣氏:Boots博姿
2017/12/23 全球购物
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
厨师个人自我鉴定范文
2014/04/19 职场文书
思想作风纪律整顿心得体会
2014/09/04 职场文书
2014年领班工作总结
2014/11/25 职场文书
客房部经理岗位职责
2015/02/02 职场文书
2015年师德表现自我评价
2015/03/05 职场文书
电影焦裕禄观后感
2015/06/09 职场文书
2015年重阳节活动主持词
2015/07/30 职场文书
多人股份制合作协议书
2016/03/19 职场文书
python数据库批量插入数据的实现(executemany的使用)
2021/04/30 Python
Goland使用Go Modules创建/管理项目的操作
2021/05/06 Golang
Python 读取千万级数据自动写入 MySQL 数据库
2022/06/28 Python