How to do it...

The following examples are taken from the Python documentation at https://docs.python.org/3/library/collections.html#collections.defaultdict:

  1. A list is a common source for default_factory, as it makes it easy to group a sequence of key:value pairs into a dictionary of lists, as follows:
      >>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
    • First, a list of tuples is created. The tuples match a string with an integer.
    • A defaultdict is created using an empty list as the factory argument.
    • The list of tuples is iterated through, assigning the tuple key:value pairs to the defaultdict list's factory.
    • When the sorted dictionary is printed, it shows that the defaultdict created a new key for each new item from the tuple's list. If a key was already present in the dictionary, then the tuple's value was added to the key's value as a new item in a list via the append function. Basically, the tuple's list was shorted to a key:value pairing that identified all the values related to a particular key.
  1. Another way to perform the previous operation is to use the dict class setdefault() method. However, setdefault() can be slower and more complex than using a defaultdict:
      >>> d = {}
>>> for k, v in s:
... d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
    • In this case, an empty dictionary is created (the same tuple's list is used in this example).
    • Next, the tuples are split into keys and values. The setdefault() method is used to assign a key with a blank value to the dictionary, then the value is added to the key's empty list (or appended to an existing value).
    • While the processing time for setdefault() may be very close to defaultdict for a small script such as this, it can add up for larger projects. In addition, using setdefault() doesn't look as intuitive as the defaultdict code.
  1. If the factory is set to an integer, the defaultdict can be used for counting:
      >>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]
    • In this example, a string is set, followed by a defaultdict using an integer as the default_factory.
    • Next, for each character in the string, an incrementer is created to count each character as the string is iterated through. As each character is looked at, it is checked to see whether it already exists in the dictionary. If not, the factory calls the int() function to generate a default count equal to zero. Then, as the rest of the string is walked through, new values receive a count of zero while existing values are incremented.
    • The final dictionary is sorted and the contents displayed. In this case, the quantity of each character in the initial string is printed to the screen.
  1. An alternative to the previous example is to use lambda functions. Because int() always returns zero, generating an alternate starting value (which could be type, not just an integer) can be accomplished with a (functionally) empty lambda:
      >>> def constant_factory(value):
... return lambda: value
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'
    • In this example, the constant_factory function accepts a value and then returns that value to the caller.
    • The defaultdict uses constant_factory to generate whatever value is passed in; in this case, it is a string.
    • The defaultdict is updated to pass in key arguments.
    • The values mapped to the dictionary keys are processed. Since an object is missing from the key arguments that were passed in, the lambda function provides it via the string that was passed to it.
  1. If the default_factory is giving the set type as an argument, the defaultdict can be used to create a dictionary of sets:
      >>> s = [("apple", 1), ("banana", 2), ("carrot", 3), ("banana", 4), ("carrot", 1), ("banana", 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
... d[k].add(v)
...
>>> sorted(d.items())
[('apple', {1}), ('banana', {2, 4}), ('carrot', {1, 3})]
    • Here, a list of tuples is created. The defaultdict is provided with an empty set as the factory argument.
    • The tuple's list is iterated through, generating the keys and values for the dictionary from the tuples. The values are added to the sets associated with the keys.
    • Printing the dictionary items shows how the various, duplicate tuples in the list have been combined into two dictionary mappings.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset