defaultdict-NickNackGus

defaultdict with deepcopy support


License
MIT
Install
pip install defaultdict-NickNackGus==1.0.2

Documentation

DefaultDict

This is a package for a defaultdict that deep copies its default value.

This can be used to implement a simple counter object, similar to the example code this is based on.

counter = DefaultDict()

for item in ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam']:
    counter[item] += 1

print("Menu contents:")
for item in counter:
    print("  {}x {}".format(counter[item], item))

Output:

Menu contents:
  1x bacon
  1x egg
  4x spam

Unlike collections.defaultdict, the default value is an object - not a factory. This allows for easier creation of nested data structures. For example, the following is valid and encouraged:

# shapes_by_color[color][shape] = count
shapes_by_color = DefaultDict(
    default=DefaultDict(
        {'total': 0},
        default=0
    )
)

with open('test/shapes.log', 'r') as fp:
    for line in fp:
        color, shape = line.split()
        shapes_by_color[color][shape] += 1
        shapes_by_color[color]['total'] += 1

for color, shapes in shapes_by_color.items():
    print("{}:".format(color))
    for shape, count in shapes.items():
        if shape == 'total':
            continue
        print("  {}x {}".format(count, shape))
    print("  Total: {}".format(count))

Output:

green:
  2x triangle
  1x circle
  Total: 3
red:
  1x octagon
  2x rhombus
  Total: 3
blue:
  1x triangle
  1x square
  Total: 2

Note that the default value is a reference, and is affected by external changes. This only affects new uses of the default value, not previous uses.

spam = DefaultDict(default=['Hello'])
print(spam['eggs'])

spam.default.append('world')
print(spam['sausage'])

print(spam)

Output:

['Hello']
['Hello', 'world']
DictWithDefault(init={'sausage': ['Hello', 'world'], 'eggs': ['Hello']}, default=['Hello', 'world'])