¿Cómo imprimir un diccionario línea por línea en Python?

166

Este es el diccionario

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

Usando esto for loop

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

Imprime lo siguiente:

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

Pero quiero que el programa lo imprima así:

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

Acabo de empezar a aprender diccionarios, así que no estoy seguro de cómo hacerlo.

Jett
fuente

Respuestas:

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

salida:

A
color : 2
speed : 70
B
color : 3
speed : 60
namit
fuente
12
Sé que esto es viejo, pero pensé que valdría la pena mencionar que esto no funciona si los autos [x] son ​​enteros. No es lo que estaba solicitando el OP, así que solo lo digo para cualquiera que se encuentre con esto asumiendo que es una solución general.
Darrel Holt
@DarrelHolt, ¿sabes cómo hacer que funcione con enteros? Porque ese es el problema que estoy enfrentando actualmente
theprowler
@theprowler Lo más cerca que puedo llegar a recrear el problema es si cars = {1:4, 2:5}se cars[x]trata de un entero asignado a la clave en xlugar de un conjunto asignado a la clave x. En este caso, no necesita usar la for y in cars[x]:línea porque solo está recuperando un valor, a menos que esté usando algo como una lista o un conjunto de enteros, entonces debería funcionar. Lo siento, han pasado unos meses, así que no puedo recordar por completo cómo llegué a la conclusión de mi comentario anterior. Podrías enviarme tu código y puedo ver si soy de alguna ayuda.
Darrel Holt
Hmm Creo que mi problema es aún peor que eso. Básicamente, analicé algunos datos de una tabla HTML, y por casualidad los almacené en un diccionario, y ahora estoy tratando de tomar esos datos del diccionario y ponerlos en un DataFrame antes de exportarlos a una tabla de Oracle. ... es bastante profundo, lo sé, pero el paso que me está deteniendo en este momento es poner los datos en un Marco de datos ... mi diccionario por alguna razón tiene una clave y todos los datos están en valores, por lo que es difícil tratando de ponerlo ordenadamente en filas y columnas ..
theprowler
118

Podrías usar el jsonmódulo para esto. La dumpsfunción en este módulo convierte un objeto JSON en una cadena con el formato adecuado que luego puede imprimir.

import json

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

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

La salida se ve como

{
    "UNA": {
        "color": 2,
        "velocidad": 70
    },
    "B": {
        "color": 3,
        "velocidad": 60
    }
}

La documentación también especifica un montón de opciones útiles para este método.

kchak
fuente
2
Es cierto, el contenido del dict debe ser serializable en json, sin embargo, la salida proporcionada aquí es mucho más limpia (por ejemplo, legible por humanos) que la salida producida por el pprint.PrettyPrinter. específicamente en el área de sangría consistente y descarte de prefijos de cadena como u'foo '.
Buffalo Rabor
Lo hago print(json.dumps(cars, indent=4, ensure_ascii=False))porque de lo contrario los caracteres que no son ASCII son ilegibles.
Boris
85

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.

Sr. Maravilloso
fuente
11
Y si el formato no es demasiado estricto, también se podría usar 'print json.dumps (obj, indent = 3)'. Eso da una representación razonable de la mayoría de las estructuras, aunque se ahoga (en mi entorno) en mi ejemplo menos trivial debido al uso de una tupla como clave ...
MrWonderful
77
¿Por qué no solo usar pprint.pprint()aquí entonces?
Martijn Pieters
1
casi hecho un creador de JSON, ¿no?
user2007447
30

Tiene una estructura anidada, por lo que también debe formatear el diccionario anidado:

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

Esto imprime:

A
color : 2
speed : 70
B
color : 3
speed : 60
Martijn Pieters
fuente
28

pprint.pprint() es una buena herramienta para este trabajo:

>>> 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}}
mac13k
fuente
6
for car,info in cars.items():
    print(car)
    for key,value in info.items():
        print(key, ":", value)
Scott Olson
fuente
4

Esto funcionará si sabe que el árbol solo tiene dos niveles:

for k1 in cars:
    print(k1)
    d = cars[k1]
    for k2 in d
        print(k2, ':', d[k2])
Benjamin Hodgson
fuente
4

Verifique el siguiente 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()))

Salida:

A
speed : 70
color : 2
B
speed : 60
color : 3
kenorb
fuente
Agradable, pero intenté convertirlo para usar esto sys.modules, pero fallé. ¿Quieres intentarlo?
not2qubit
4

Prefiero el formato limpio de yaml:

import yaml
yaml.dump(cars)

salida:

A:
  color: 2
  speed: 70
B:
  color: 3
  speed: 60
gizzmole
fuente
Tienes que pip install PyYAMLprimero.
Boris
0
###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
fuente
0
# 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
El hombre mismo
fuente
0

Aquí está mi solución al problema. Creo que es similar en enfoque, pero un poco más simple que algunas de las otras respuestas. También permite un número arbitrario de sub-diccionarios y parece funcionar para cualquier tipo de datos (incluso lo probé en un diccionario que tenía funciones como valores):

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)
rocas
fuente
-1

Modificando el código MrWonderful

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
Vlad
fuente
1
¿Qué modificaste? ¿Cuál es la salida?
Andreas Haferburg