210

This is the dictionary

cars = {'A':{'speed':70,
        'color':2},
        'B':{'speed':60,
        'color':3}}

Using this for loop

for keys,values in cars.items():
    print(keys)
    print(values)

It prints the following:

B
{'color': 3, 'speed': 60}
A
{'color': 2, 'speed': 70}

But I want the program to print it like this:

B
color : 3
speed : 60
A
color : 2
speed : 70

I just started learning dictionaries so I'm not sure how to do this.

Jett
  • 2,421
  • 5
  • 16
  • 14

16 Answers16

174
for x in cars:
    print (x)
    for y in cars[x]:
        print (y,':',cars[x][y])

output:

A
color : 2
speed : 70
B
color : 3
speed : 60
namit
  • 6,780
  • 4
  • 35
  • 41
  • 18
    I know this is old, but I thought it would be worth mentioning that this doesn't work if cars[x] is integers. It isn't what the OP was requesting, so I'm just saying it for anybody that stumbles upon this assuming it's a blanket solution. – Darrel Holt Apr 21 '16 at 07:09
  • @DarrelHolt do you know how to make it work with integers? Because that's the problem I'm currently facing – theprowler Dec 21 '16 at 16:32
  • @theprowler The closest I can get to recreating the problem is if `cars = {1:4, 2:5}` then `cars[x]` is an integer mapped to the key `x` rather than a set mapped to the key `x`. In this case, you don't need to use the `for y in cars[x]:` line because there's only one value you're retrieving, unless you're using something like a list or set of integers then it should work. Sorry, it's been a few months so I can't completely remember how I came to the conclusion of my previous comment. You could send me your code and I can see if I'm any help. – Darrel Holt Dec 21 '16 at 20:54
  • Hmm. I think my problem is even worse than that. Basically I've parsed out some data from an HTML table, and I happened to store it in a dictionary, and now I'm trying to take that dictionary data and put it into a DataFrame before I export it all to an Oracle table....it's pretty in depth I know, but the step that is holding me up right now is putting the data into a DataFrame....my dictionary for some reason has one key and all the data is in values, so it's difficult trying to put it neatly into rows and columns.. – theprowler Dec 22 '16 at 14:53
167

You could use the json module for this. The dumps function in this module converts a JSON object into a properly formatted string which you can then print.

import json

cars = {'A':{'speed':70, 'color':2},
        'B':{'speed':60, 'color':3}}

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

The output looks like

{
    "A": {
        "color": 2,
        "speed": 70
    },
    "B": {
        "color": 3,
        "speed": 60
    }
}

The documentation also specifies a bunch of useful options for this method.

Bob Stein
  • 16,271
  • 10
  • 88
  • 101
kchak
  • 7,570
  • 4
  • 20
  • 31
  • 2
    true, the contents of the dict must be serializable into json, however, the output provided here is far cleaner (e.g., human readable) than output produced by the pprint.PrettyPrinter. specifically in the area of consistent indentation and discarding of string prefixes such as u'foo'. – Buffalo Rabor May 09 '18 at 00:17
  • I do `print(json.dumps(cars, indent=4, ensure_ascii=False))` because otherwise non-ASCII characters are unreadable. – Boris Verkhovskiy Apr 22 '20 at 16:36
87

A more generalized solution that handles arbitrarily-deeply nested dicts and lists would be:

def dumpclean(obj):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if hasattr(v, '__iter__'):
                print k
                dumpclean(v)
            else:
                print '%s : %s' % (k, v)
    elif isinstance(obj, list):
        for v in obj:
            if hasattr(v, '__iter__'):
                dumpclean(v)
            else:
                print v
    else:
        print obj

This produces the output:

A
color : 2
speed : 70
B
color : 3
speed : 60

I ran into a similar need and developed a more robust function as an exercise for myself. I'm including it here in case it can be of value to another. In running nosetest, I also found it helpful to be able to specify the output stream in the call so that sys.stderr could be used instead.

import sys

def dump(obj, nested_level=0, output=sys.stdout):
    spacing = '   '
    if isinstance(obj, dict):
        print >> output, '%s{' % ((nested_level) * spacing)
        for k, v in obj.items():
            if hasattr(v, '__iter__'):
                print >> output, '%s%s:' % ((nested_level + 1) * spacing, k)
                dump(v, nested_level + 1, output)
            else:
                print >> output, '%s%s: %s' % ((nested_level + 1) * spacing, k, v)
        print >> output, '%s}' % (nested_level * spacing)
    elif isinstance(obj, list):
        print >> output, '%s[' % ((nested_level) * spacing)
        for v in obj:
            if hasattr(v, '__iter__'):
                dump(v, nested_level + 1, output)
            else:
                print >> output, '%s%s' % ((nested_level + 1) * spacing, v)
        print >> output, '%s]' % ((nested_level) * spacing)
    else:
        print >> output, '%s%s' % (nested_level * spacing, obj)

Using this function, the OP's output looks like this:

{
   A:
   {
      color: 2
      speed: 70
   }
   B:
   {
      color: 3
      speed: 60
   }
}

which I personally found to be more useful and descriptive.

Given the slightly less-trivial example of:

{"test": [{1:3}], "test2":[(1,2),(3,4)],"test3": {(1,2):['abc', 'def', 'ghi'],(4,5):'def'}}

The OP's requested solution yields this:

test
1 : 3
test3
(1, 2)
abc
def
ghi
(4, 5) : def
test2
(1, 2)
(3, 4)

whereas the 'enhanced' version yields this:

{
   test:
   [
      {
         1: 3
      }
   ]
   test3:
   {
      (1, 2):
      [
         abc
         def
         ghi
      ]
      (4, 5): def
   }
   test2:
   [
      (1, 2)
      (3, 4)
   ]
}

I hope this provides some value to the next person looking for this type of functionality.

MrWonderful
  • 2,530
  • 1
  • 16
  • 22
  • 11
    And if the format is not overly strict, one could also use 'print json.dumps(obj, indent=3)'. That gives a reasonable representation of most structures, though it does choke (in my environment) on my less-trivial example due to the use of a tuple as a key... – MrWonderful Jan 10 '14 at 16:17
  • 9
    Why not just use [`pprint.pprint()`](https://docs.python.org/2/library/pprint.html#pprint.pprint) here then? – Martijn Pieters Jul 03 '14 at 11:09
  • 1
    almost made a JSON creator, no? – user2007447 Jan 14 '15 at 12:56
56

pprint.pprint() is a good tool for this job:

>>> import pprint
>>> cars = {'A':{'speed':70,
...         'color':2},
...         'B':{'speed':60,
...         'color':3}}
>>> pprint.pprint(cars, width=1)
{'A': {'color': 2,
       'speed': 70},
 'B': {'color': 3,
       'speed': 60}}
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
mac13k
  • 2,423
  • 23
  • 34
  • 3
    This seem to be the simplest and best solution by far, as it can also handle *sets, tuples* and *lists* when nested in the *dict*. – not2qubit Dec 23 '20 at 22:21
  • I think it is better to use `pprint` without `width` option, otherwise it also breaks the phrases that have spaces between each word. – Celuk Oct 04 '22 at 14:04
33

You have a nested structure, so you need to format the nested dictionary too:

for key, car in cars.items():
    print(key)
    for attribute, value in car.items():
        print('{} : {}'.format(attribute, value))

This prints:

A
color : 2
speed : 70
B
color : 3
speed : 60
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
16

I prefer the clean formatting of yaml:

import yaml
print(yaml.dump(cars))

output:

A:
  color: 2
  speed: 70
B:
  color: 3
  speed: 60
SaTa
  • 2,422
  • 2
  • 14
  • 26
gizzmole
  • 1,437
  • 18
  • 26
8
for car,info in cars.items():
    print(car)
    for key,value in info.items():
        print(key, ":", value)
Scott Olson
  • 3,513
  • 24
  • 26
5

This will work if you know the tree only has two levels:

for k1 in cars:
    print(k1)
    d = cars[k1]
    for k2 in d
        print(k2, ':', d[k2])
Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
4

Check the following one-liner:

print('\n'.join("%s\n%s" % (key1,('\n'.join("%s : %r" % (key2,val2) for (key2,val2) in val1.items()))) for (key1,val1) in cars.items()))

Output:

A
speed : 70
color : 2
B
speed : 60
color : 3
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • Nice one, but I tried to convert it to use this with `sys.modules`, but I failed. Wanna have a go at it? – not2qubit Oct 22 '18 at 20:32
0

Here is my solution to the problem. I think it's similar in approach, but a little simpler than some of the other answers. It also allows for an arbitrary number of sub-dictionaries and seems to work for any datatype (I even tested it on a dictionary which had functions as values):

def pprint(web, level):
    for k,v in web.items():
        if isinstance(v, dict):
            print('\t'*level, f'{k}: ')
            level += 1
            pprint(v, level)
            level -= 1
        else:
            print('\t'*level, k, ": ", v)
rocksNwaves
  • 5,331
  • 4
  • 38
  • 77
  • I don't see how this is simpler than other answers. Certainly not for readability. Also would be great to see some example output from this. – not2qubit Dec 23 '20 at 21:59
0

Made one liner. Outputs exactly what you want.

cars = {'A':{'speed':70,
        'color':2},
        'B':{'speed':60,
        'color':3}}
print('\n'.join(f'{k}\n'+'\n'.join(f'{k2} : {v}' for k2,v in reversed(cars[k].items())) for k in reversed(cars)))

Also, tried run with timeit all solutions. And mine was always slowest.

Giuppox
  • 1,393
  • 9
  • 35
TheVorkMan
  • 57
  • 4
-1
###newbie exact answer desired (Python v3):
###=================================
"""
cars = {'A':{'speed':70,
        'color':2},
        'B':{'speed':60,
        'color':3}}
"""

for keys, values in  reversed(sorted(cars.items())):
    print(keys)
    for keys,values in sorted(values.items()):
        print(keys," : ", values)

"""
Output:
B
color  :  3
speed  :  60
A
color  :  2
speed  :  70

##[Finished in 0.073s]
"""
bpr67
  • 1
-1
# Declare and Initialize Map
map = {}

map ["New"] = 1
map ["to"] = 1
map ["Python"] = 5
map ["or"] = 2

# Print Statement
for i in map:
  print ("", i, ":", map[i])

#  New : 1
#  to : 1
#  Python : 5
#  or : 2
-1

Use this.

cars = {'A':{'speed':70,
        'color':2},
        'B':{'speed':60,
        'color':3}}

print(str(cars).replace(",", ",\n"))

output:

{'A': {'speed': 70,
 'color': 2},
 'B': {'speed': 60,
 'color': 3}}
-1

I think list comprehension is the cleanest way to do this:

mydict = {a:1, b:2, c:3}

[(print("key:", key, end='\t'), print('value:', value)) for key, value in mydict.items()]
Javad
  • 2,033
  • 3
  • 13
  • 23
-2

Modifying MrWonderful code

import sys

def print_dictionary(obj, ident):
    if type(obj) == dict:
        for k, v in obj.items():
            sys.stdout.write(ident)
            if hasattr(v, '__iter__'):
                print k
                print_dictionary(v, ident + '  ')
            else:
                print '%s : %s' % (k, v)
    elif type(obj) == list:
        for v in obj:
            sys.stdout.write(ident)
            if hasattr(v, '__iter__'):
                print_dictionary(v, ident + '  ')
            else:
                print v
    else:
        print obj
MrWonderful
  • 2,530
  • 1
  • 16
  • 22
Vlad
  • 4,425
  • 1
  • 30
  • 39