43

I am using default dict. I need to pprint.

However, when I pprint ...this is how it looks.

defaultdict(<functools.partial object at 0x1f68418>, {u'300:250': defaultdict(<functools.partial object at 0x1f683c0>, {0: defaultdict(<type 'list'>, {u'agid1430864021': {u'status': u'0', u'exclude_regi..........

How to I get pprint to work with default dict?

Amanda
  • 12,099
  • 17
  • 63
  • 91
Tampa
  • 75,446
  • 119
  • 278
  • 425

5 Answers5

45

I've used pprint(dict(defaultdict)) before as a work-around.

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
  • 22
    I've found this solution does not give the desired effect if the object is a nested hierarchy of deafultdict objects. – krd Mar 14 '14 at 21:02
  • 5
    For nested defaultdicts: `pprint({k: dict(v) for k, v in dict(group_ids).items()})` –  Nov 14 '15 at 18:00
25

The best solution I've found is a bit of a hack, but an elegant one (if a hack can ever be):

class PrettyDefaultDict(collections.defaultdict):
    __repr__ = dict.__repr__

And then use the PrettyDefaultDict class instead of collections.defaultdict. It works because of the way the pprint module works (at least on 2.7):

r = getattr(typ, "__repr__", None)
if issubclass(typ, dict) and r is dict.__repr__:
    # follows pprint dict formatting

This way we "trick" pprint into thinking that our dictionary class is just like a normal dict.

RedGlow
  • 773
  • 7
  • 13
18

If you don't have to use pprint, you can use json to pretty-print the defaultdict:

print(json.dumps(my_default_dict, indent=4))

This also works for nested defaultdicts.

Markus
  • 1,635
  • 15
  • 17
5

I really like this solution for dealing with nested defaultdicts. It's a bit of a hack, but does the job neatly when pdbing:

import json
data_as_dict = json.loads(json.dumps(data_as_defaultdict))
print(data_as_dict)

From: https://stackoverflow.com/a/32303615/4526633

Community
  • 1
  • 1
jarekwg
  • 375
  • 3
  • 8
4

In the same vein as Jon Clements' answer, if this is a common operation for you, you might consider subclassing defaultdict to override its repr method, as shown below.

Input:

from collections import defaultdict

class prettyDict(defaultdict):
    def __init__(self, *args, **kwargs):
        defaultdict.__init__(self,*args,**kwargs)

    def __repr__(self):
        return str(dict(self))

foo = prettyDict(list)

foo['bar'].append([1,2,3])
foo['foobar'].append([4,5,6,7,8])

print(foo)

Output:

{'foobar': [[4, 5, 6, 7, 8]], 'bar': [[1, 2, 3]]}
Mr. Squig
  • 2,755
  • 17
  • 10