Come stampare un dizionario riga per riga in Python?


166

Questo è il dizionario

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

Usando questo for loop

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

Stampa quanto segue:

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

Ma voglio che il programma lo stampi in questo modo:

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

Ho appena iniziato a studiare dizionari, quindi non sono sicuro di come farlo.

Risposte:


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

produzione:

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

12
So che questo è vecchio, ma ho pensato che varrebbe la pena ricordare che questo non funziona se le macchine [x] sono numeri interi. Non è ciò che l'OP stava chiedendo, quindi lo sto solo dicendo a chiunque si imbatta in questo presupponendo che sia una soluzione generale.
Darrel Holt,

@DarrelHolt sai come farlo funzionare con numeri interi? Perché questo è il problema che sto affrontando attualmente
theprowler

@theprowler Il più vicino che riesco a ottenere per ricreare il problema è se cars = {1:4, 2:5}quindi cars[x]un numero intero è mappato sulla chiave xpiuttosto che un set mappato sulla chiave x. In questo caso, non è necessario utilizzare la for y in cars[x]:linea perché c'è solo un valore che stai recuperando, a meno che tu non stia usando qualcosa come un elenco o un insieme di numeri interi, quindi dovrebbe funzionare. Siamo spiacenti, sono passati alcuni mesi, quindi non ricordo completamente come sono arrivato alla conclusione del mio commento precedente. Potresti inviarmi il tuo codice e posso vedere se sono di aiuto.
Darrel Holt,

Hmm. Penso che il mio problema sia anche peggio di così. Fondamentalmente ho analizzato alcuni dati da una tabella HTML e mi è capitato di memorizzarli in un dizionario, e ora sto cercando di prendere quei dati del dizionario e inserirli in un DataFrame prima di esportarli tutti in una tabella Oracle. ... è abbastanza approfondito, lo so, ma il passo che mi sta trattenendo in questo momento è mettere i dati in un DataFrame .... il mio dizionario per qualche ragione ha una chiave e tutti i dati sono in valori, quindi è difficile cercando di metterlo ordinatamente in file e colonne ..
theprowler

118

È possibile utilizzare il jsonmodulo per questo. La dumpsfunzione in questo modulo converte un oggetto JSON in una stringa correttamente formattata che è quindi possibile stampare.

import json

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

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

L'output è simile

{
    "A": {
        "colore": 2,
        "velocità": 70
    },
    "B": {
        "colore": 3,
        "velocità": 60
    }
}

La documentazione specifica anche un mucchio di opzioni utili per questo metodo.


2
vero, il contenuto del dict deve essere serializzabile in json, tuttavia l'output fornito qui è molto più pulito (ad esempio, leggibile dall'uomo) dell'output prodotto da pprint.PrettyPrinter. in particolare nell'area del rientro e dello scarto coerenti di prefissi di stringa come u'foo '.
Buffalo Rabor,

Lo faccio print(json.dumps(cars, indent=4, ensure_ascii=False))perché altrimenti i caratteri non ASCII sono illeggibili.
Boris,

85

Una soluzione più generalizzata che gestisce elenchi e elenchi nidificati in modo arbitrario sarebbe:

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

Questo produce l'output:

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

Mi sono imbattuto in un'esigenza simile e ho sviluppato una funzione più solida come esercizio per me stesso. Lo sto includendo qui nel caso in cui possa essere utile per un altro. Nell'esecuzione di nosetest, ho anche trovato utile poter specificare il flusso di output nella chiamata in modo da poter utilizzare sys.stderr.

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 questa funzione, l'output dell'OP è simile al seguente:

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

che ho trovato personalmente più utile e descrittivo.

Dato l'esempio leggermente meno banale di:

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

La soluzione richiesta dall'OP produce questo:

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

mentre la versione "migliorata" produce questo:

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

Spero che questo offra un valore alla prossima persona che cerca questo tipo di funzionalità.


11
E se il formato non è eccessivamente rigido, si potrebbe anche usare "print json.dumps (obj, indent = 3)". Ciò fornisce una rappresentazione ragionevole della maggior parte delle strutture, anche se soffoca (nel mio ambiente) il mio esempio meno banale a causa dell'uso di una tupla come chiave ...
MrWonderful

7
Perché non solo usare pprint.pprint() qui allora?
Martijn Pieters

1
quasi fatto un creatore di JSON, no?
user2007447

30

Hai una struttura nidificata, quindi devi anche formattare il dizionario nidificato:

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

Questo stampa:

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

28

pprint.pprint() è un buon strumento per questo lavoro:

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

Funzionerà se sai che l'albero ha solo due livelli:

for k1 in cars:
    print(k1)
    d = cars[k1]
    for k2 in d
        print(k2, ':', d[k2])

4

Controllare il seguente 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()))

Produzione:

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

Bello, ma ho provato a convertirlo per usarlo sys.modules, ma non ci sono riuscito. Vuoi provarci?
not2qubit

4

Preferisco la formattazione pulita di yaml:

import yaml
yaml.dump(cars)

produzione:

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

Devi pip install PyYAMLprima.
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

Ecco la mia soluzione al problema. Penso che sia simile nell'approccio, ma un po 'più semplice di alcune delle altre risposte. Permette anche un numero arbitrario di sotto-dizionari e sembra funzionare per qualsiasi tipo di dati (l'ho persino testato su un dizionario che aveva funzioni come valori):

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

Modifica del codice 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
Cosa hai modificato? Qual è l'output?
Andreas Haferburg,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.