CodingBison

Dictionaries have several built-in methods. These methods allow us to do various useful operations. We use the dir() function to get a list of various dictionary attributes (some of these being methods).

 [user@codingbison]$ python3
 Python 3.2.1 (default, Jul 11 2011, 18:55:33) 
 [GCC 4.6.1 20110627 (Red Hat 4.6.1-1)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> 
 >>> varDict = {}
 >>> 
 >>> dir(varDict)
 ['__class__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', 
 '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', 
 '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', 
 '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 
 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
 >>> 

The above list has various callable methods (the ones that do not have starting and trailing double underscores). Let us understand some of these methods.

Method keys() returns all the keys present in the dictionary. Method values() returns all the values present in the dictionary. Lastly, if we want to get a list of both, then we can use the method items(). Let us print the keys, values or key/value pairs for a simple dictionary:

 [user@codingbison]$ python3
 Python 3.2.1 (default, Jul 11 2011, 18:55:33) 
 [GCC 4.6.1 20110627 (Red Hat 4.6.1-1)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> 
 >>> varDict = {"zebra": "Equus quagga", "guanaco": "Lama guanicoe"}
 >>> 
 >>> print(varDict.keys())
 dict_keys(['guanaco', 'zebra'])
 >>> 
 >>> print(type(varDict.keys()))
 <class 'dict_keys'>
 >>> 
 >>> print(varDict.values())
 dict_values(['Lama guanicoe', 'Equus quagga'])
 >>> 
 >>> print(type(varDict.values()))
 <class 'dict_values'>
 >>> 
 >>> print(varDict.items())
 dict_items([('guanaco', 'Lama guanicoe'), ('zebra', 'Equus quagga')])
 >>> 
 >>> print(type(varDict.items()))
 <class 'dict_items'>
 >>>

The above output shows that the type of the returned values of these methods is not a list; instead, they are iterators. This was not always the case. With Python 2.x, these methods (keys(), values(), and items()) return a list. Thus, we can use list methods on the returned values of these methods with Python 2.x. But, since Python 3.x does not return a list with these methods, using a list method like sort would simply be an error!

We print below the return value type of these methods for Python 2.x.

 [user@codingbison]$ python
 Python 2.7.3 (default, Apr 13 2012, 20:15:24) 
 [GCC 4.6.3 20120306 (Red Hat 4.6.3-2)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> 
 >>> varDict = {"zebra" : "Equus quagga", "guanaco" : "Lama guanicoe"}
 >>> 
 >>> print(varDict.keys())
 ['guanaco', 'zebra']
 >>> print(type(varDict.keys()))
 <type 'list'>
 >>> 
 >>> print(varDict.values())
 ['Lama guanicoe', 'Equus quagga']
 >>> print(type(varDict.values()))
 <type 'list'>
 >>> 
 >>> print(varDict.items())
 [('guanaco', 'Lama guanicoe'), ('zebra', 'Equus quagga')]
 >>> print(type(varDict.items()))
 <type 'list'>
 >>> 

copy and deepcopy

The copy method makes a copy of the dictionary. This way, even if we modify the copy, the original dictionary remains intact. Note that we can always assign a dictionary to a new dictionary as in "varNewDict = varOldDict"; however, in doing so, the new dictionary is simply a reference of the old dictionary and modifying one will modify the other.

In the example provided below, we make a copy of an existing dictionary. Also, when we clear the copy dictionary, then the original dictionary remains unaffected; the clear() method deletes all the key/value mappings from the dictionary.

 [user@codingbison]$ python3
 Python 3.2.1 (default, Jul 11 2011, 18:55:33) 
 [GCC 4.6.1 20110627 (Red Hat 4.6.1-1)] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> 
 >>> varDict = {"zebra" : "Equus quagga", "guanaco" : "Lama guanicoe"}
 >>> 
 >>> varDictCopy = varDict.copy()
 >>> varDictCopy.clear()
 >>> print(varDictCopy)
 {}
 >>> 
 >>> print(varDict)
 {'guanaco': 'Lama guanicoe', 'zebra': 'Equus quagga'}
 >>> 

However, the copy() method (like list slicing) is a shallow copy. This means that the elements of the dictionary are not actually copied -- instead, Python places a reference of the elements from the old copy to the new copy. To use a deep copy, where even the elements are copied (and not referenced), we can use the deepcopy() method of the copy module. Note that the copy() module also provides a copy() method which will also (shallow) copy a dictionary.

In the following example, the varDict dictionary has varListRoar list as a value of one of its keys. When we make a copy of the varDict (varDictShallowCopy) and add a value ("elephant") to the varListRoar list, then the addition shows up in varDictShallowCopy as well! However, when we do a deepcopy(), then the addition ("alligator") to the varListRoar does not show up in the varDictDeepCopy.

 >>> varListRoar = ["tiger", "lion"]
 >>> varDict = {"roars" : varListRoar, "howls" : "wolfs"}
 >>> print(varDict)
 {'howls': 'wolfs', 'roars': ['tiger', 'lion']}
 >>> 
 >>> varDictShallowCopy = varDict.copy()
 >>> varListRoar.append("elephant")
 >>> print(varDictShallowCopy)
 {'howls': 'wolfs', 'roars': ['tiger', 'lion', 'elephant']}
 >>> 
 >>> import copy
 >>> varDictDeepCopy = copy.deepcopy(varDict)
 >>> varListRoar.append("alligator")
 >>> print(varDictDeepCopy)
 {'howls': 'wolfs', 'roars': ['tiger', 'lion', 'elephant']}
 >>>




comments powered by Disqus