145

I've just started to learn python and I'm building a text game. I want an inventory system, but I can't seem to print out the dictionary without it looking ugly.

This is what I have so far:

def inventory():
    for numberofitems in len(inventory_content.keys()):
        inventory_things = list(inventory_content.keys())
        inventory_amounts = list(inventory_content.values())
        print(inventory_things[numberofitems])
codeforester
  • 39,467
  • 16
  • 112
  • 140
Raphael Huang
  • 1,453
  • 2
  • 8
  • 5
  • 4
    _"nicely"_ is a subjective term, but perhaps you are looking for something like [this](https://stackoverflow.com/questions/3229419/pretty-printing-nested-dictionaries-in-python). – Christian Dean Jun 22 '17 at 03:19
  • 1
    FYI, this sample code doesn't work at all. The `for` loop here will be an error. I think you meant to use a `range`. Also, `inventory_amounts` isn't used, so you aren't printing the values. – sudo Jun 22 '17 at 03:19
  • related: https://stackoverflow.com/questions/3229419/how-to-pretty-print-nested-dictionaries – Ciro Santilli OurBigBook.com Nov 28 '19 at 16:13

10 Answers10

173

I like the pprint module (Pretty Print) included in Python. It can be used to either print the object, or format a nice string version of it.

import pprint

# Prints the nicely formatted dictionary
pprint.pprint(dictionary)

# Sets 'pretty_dict_str' to the formatted string value
pretty_dict_str = pprint.pformat(dictionary)

But it sounds like you are printing out an inventory, which users will likely want shown as something more like the following:

def print_inventory(dct):
    print("Items held:")
    for item, amount in dct.items():  # dct.iteritems() in Python 2
        print("{} ({})".format(item, amount))

inventory = {
    "shovels": 3,
    "sticks": 2,
    "dogs": 1,
}

print_inventory(inventory)

which prints:

Items held:
shovels (3)
sticks (2)
dogs (1)
StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
foslock
  • 3,639
  • 2
  • 22
  • 26
107

My favorite way:

import json
print(json.dumps(dictionary, indent=4, sort_keys=True))
Ofer Sadan
  • 11,391
  • 5
  • 38
  • 62
  • 2
    Note that `sort_keys=True` throws an error if there are keys that are of different types (eg. integer and string keys). – Kevin May 08 '18 at 05:58
  • 5
    Your dictionary must only contain JSON-serializable objects, which are strings, various numbers, and booleans, for this to work. If that's the case, this is the easiest way with the nicest formatting. – sudo Jul 31 '18 at 18:31
  • 15
    @sudo you can use `default=str` so if something is not JSON-serializable it is first converted to a string – arod Dec 05 '18 at 20:30
  • Can it be sorted based on values? – alper Jan 01 '21 at 15:01
30

Here's the one-liner I'd use. (Edit: works for things that aren't JSON-serializable too)

print("\n".join("{}\t{}".format(k, v) for k, v in dictionary.items()))

Explanation: This iterates through the keys and values of the dictionary, creating a formatted string like key + tab + value for each. And "\n".join(... puts newlines between all those strings, forming a new string.

Example:

>>> dictionary = {1: 2, 4: 5, "foo": "bar"}
>>> print("\n".join("{}\t{}".format(k, v) for k, v in dictionary.items()))
1   2
4   5
foo bar
>>>

Edit 2: Here's a sorted version.

"\n".join("{}\t{}".format(k, v) for k, v in sorted(dictionary.items(), key=lambda t: str(t[0])))
sudo
  • 5,604
  • 5
  • 40
  • 78
7

I would suggest to use beeprint instead of pprint.

Examples:

pprint

{'entities': {'hashtags': [],
              'urls': [{'display_url': 'github.com/panyanyany/beeprint',
                        'indices': [107, 126],
                        'url': 'https://github.com/panyanyany/beeprint'}],
              'user_mentions': []}}

beeprint

{
  'entities': {
    'hashtags': [],
    'urls': [
      {
        'display_url': 'github.com/panyanyany/beeprint',
        'indices': [107, 126],
        'url': 'https://github.com/panyanyany/beeprint'}],
      },
    ],
    'user_mentions': [],
  },
}
Simon
  • 5,464
  • 6
  • 49
  • 85
dtar
  • 1,469
  • 12
  • 17
  • but how do you use it? I tried `from beeprint import pp` just like in the doc, then tried calling pp(dictionary_name) but it doesn't work. – fayssal el ansari Mar 12 '22 at 09:24
3

Yaml is typically much more readable, especially if you have complicated nested objects, hierarchies, nested dictionaries etc:

First make sure you have pyyaml module:

pip install pyyaml

Then,

import yaml
print(yaml.dump(my_dict))
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
  • `sudo apt install python-yaml` for Ubuntu 16.04 users. There is a small flaw when a dictionary value string contains `,` but that is minor output flaw. Otherwise a great tool. – WinEunuuchs2Unix Sep 27 '20 at 22:49
2

Since Python 3.6 you can use f-strings to write @sudo's one-liner even more compact

print("\n".join(f"{k}\t{v}" for k, v in dictionary.items()))
Robert
  • 1,357
  • 15
  • 26
0

Agree, "nicely" is very subjective. See if this helps, which I have been using to debug dict

for i in inventory_things.keys():
    logger.info('Key_Name:"{kn}", Key_Value:"{kv}"'.format(kn=i, kv=inventory_things[i]))
adiga
  • 34,372
  • 9
  • 61
  • 83
0

I wrote this function to print simple dictionaries:

def dictToString(dict):
  return str(dict).replace(', ','\r\n').replace("u'","").replace("'","")[1:-1]
adiga
  • 34,372
  • 9
  • 61
  • 83
Nautilus
  • 180
  • 2
  • 6
0

I did create function (in Python 3):

def print_dict(dict):
    print(

    str(dict)
    .replace(', ', '\n')
    .replace(': ', ':\t')
    .replace('{', '')
    .replace('}', '')

    )
0

Maybe it doesn't fit all the needs but I just tried this and it got a nice formatted output So just convert the dictionary to Dataframe and that's pretty much all

pd.DataFrame(your_dic.items())

You can also define columns to assist even more the readability

pd.DataFrame(your_dic.items(),columns={'Value','key'})

So just give a try :

print(pd.DataFrame(your_dic.items(),columns={'Value','key'}))
John
  • 974
  • 8
  • 16