Una solución más generalizada que maneja dictados y listas arbitrariamente anidadas sería:
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
Esto produce la salida:
A
color : 2
speed : 70
B
color : 3
speed : 60
Me encontré con una necesidad similar y desarrollé una función más robusta como ejercicio para mí. Lo incluyo aquí en caso de que pueda ser de valor para otro. Al ejecutar nosetest, también me pareció útil poder especificar la secuencia de salida en la llamada para que se pueda usar sys.stderr en su lugar.
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)
Usando esta función, la salida del OP se ve así:
{
A:
{
color: 2
speed: 70
}
B:
{
color: 3
speed: 60
}
}
que personalmente encontré más útil y descriptivo.
Dado el ejemplo un poco menos trivial de:
{"test": [{1:3}], "test2":[(1,2),(3,4)],"test3": {(1,2):['abc', 'def', 'ghi'],(4,5):'def'}}
La solución solicitada por el OP produce esto:
test
1 : 3
test3
(1, 2)
abc
def
ghi
(4, 5) : def
test2
(1, 2)
(3, 4)
mientras que la versión 'mejorada' produce esto:
{
test:
[
{
1: 3
}
]
test3:
{
(1, 2):
[
abc
def
ghi
]
(4, 5): def
}
test2:
[
(1, 2)
(3, 4)
]
}
Espero que esto brinde algún valor a la próxima persona que busque este tipo de funcionalidad.