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

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

先来看一个示例:linux

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,就像下面这样:spa

>>> 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()这一组函数就废除了。”orm

不过更加有意思的是,这个答案虽然被采纳,下面的评论却指出,这种说法并不许确,在 3.x 里 items() 的行为和 2.x 的 iteritems() 不同,它实际上返回的是一个"full sequence-protocol object",这个对象可以反映出 dict 的变化,后来在 Python 2.7 里面也加入了另一个函数 viewitems() 和 3.x 的这种行为保持一致
为了证明评论中的说法,我作了下面的测试,注意观察测试中使用的Python版本:htm

测试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程序设计有必定的借鉴价值。

相关文章
相关标签/搜索