A usage instance of the dictionary items of series of functions in Python

  • 2020-04-02 13:58:30
  • OfStack

This article illustrates the use of the dictionary items() series of functions in Python, which is a good reference for Python programming. Specific analysis is as follows:

Let's start with an example:


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>') 

The program simply generates HTML tags, which are available only in Python 3.x.

At first I just noticed that keyvals, a dictionary-type variable that generates a list of tag attributes, was constructed in an interesting way, with two %s for one item, so I looked up the relevant information and pulled out quite a few things, which I'll summarize here.

Note: for all versions of the Python interpreter below, 2.x corresponds to 2.7.3 and 3.x to 3.4.1
In Python 2.x, the method for items in the official document says this: generate a list of (key, value) pairs, as follows:


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

During the search, I came across a question on stackoverflow: what's the difference between dict.items() and dict.iteritems()? ", the first answer roughly means something like this:

"Items () originally returned a list of all the elements of dict, as shown above, but since this was a waste of memory, it was added later. Since Python 2.2,) iteritems(), iterkeys(), and itervalues() have been used to return an iterator to save memory, but items() itself returns such an iterator in 3.x, so the behavior of items() in 3.x is the same as that of iteritems() in 2.x, and iteritems() is abolished.

But more interestingly, although the answer is adopted, the comments are pointed out, that is not accurate, in 3 x the items in the behavior of the (a) and (2) x iteritems () are different, it returns a "full sequence - protocol object", this object can reflect the variation of dict, later in Python 2.7 joined another function viewitems () and (3) x of this kind of behavior
To verify the claims in the comments, I did the following test, paying attention to the Python version used in the test:

Test 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')]) 

Test 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)]) 

You can see that in Python 3.x, both the iteritems() and viewitems() methods have been abolished, and the item() result is the same as the viewitems() in 2.x.
2. The contents returned by iteritems() and viewitems() in x can be traversed with a for, as shown below


>>> for k, v in it: 
...  print k, v 
...  
quantity 6 
size large 
>>> for k, v in vi: 
...  print k, v 
...  
quantity 6 
size large 

What is the difference between the two? Viewitems () returns a view object that reflects a change in the dictionary, as in the above example, if you add a key-value combination to d before using the variables it and vi, the difference is easy to see.


>>> 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 

In the third line, we insert a new element in d, vi can continue traversing, and the new traversal can reflect the change of d, but when traversing it, error is reported that the size of the dictionary has changed during traversing, and the traversal fails.

To sum up, in 2 x, was originally the items () this method, but because is a waste of memory, so I join the iteritems () method, is used to return an iterator, in 3 x inside the items () the behavior of the modified to return a view object, make it the object returned can also reflect the change of the original dictionary, at the same time in 2.7 and added viewitems () down compatible with this feature.
So there is no need to worry about the differences in 3.x, because there is only one items() method left.

I believe that the examples described in this article have a certain reference value for your Python programming.


Related articles: