¿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.

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

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.


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.


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

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}}

6
for car,info in cars.items():
    print(car)
    for key,value in info.items():
        print(key, ":", value)

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])

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

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

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]
"""

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

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)

-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

1
¿Qué modificaste? ¿Cuál es la salida?
Andreas Haferburg
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.