Como imprimir um dicionário linha por linha no Python?

166

Este é o dicionário

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

Usando isto for loop

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

Imprime o seguinte:

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

Mas quero que o programa o imprima assim:

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

Comecei a aprender dicionários, então não tenho certeza de como fazer isso.

Jett
fonte

Respostas:

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

resultado:

A
color : 2
speed : 70
B
color : 3
speed : 60
namit
fonte
12
Eu sei que isso é antigo, mas achei que valeria a pena mencionar que isso não funciona se carros [x] forem números inteiros. Não é o que o OP estava solicitando, então estou dizendo isso para qualquer um que se deparar com isso, assumindo que é uma solução geral.
Darrel Holt
@DarrelHolt você sabe como fazê-lo funcionar com números inteiros? Porque esse é o problema que estou enfrentando atualmente
theprowler
@theprowler O mais próximo que pode chegar a recriar o problema é se cars = {1:4, 2:5}, em seguida, cars[x]é um inteiro mapeado para a chave xem vez de um conjunto mapeado para a chave x. Nesse caso, você não precisa usar a for y in cars[x]:linha porque há apenas um valor que está sendo recuperado, a menos que esteja usando algo como uma lista ou conjunto de números inteiros, pois deve funcionar. Desculpe, já faz alguns meses, então não me lembro completamente de como cheguei à conclusão do meu comentário anterior. Você poderia me enviar seu código e posso ver se tenho alguma ajuda.
Darrel Holt
Hmm. Eu acho que meu problema é ainda pior do que isso. Basicamente, analisei alguns dados de uma tabela HTML e os armazenei em um dicionário, e agora estou tentando pegar esses dados do dicionário e colocá-los em um DataFrame antes de exportá-los para uma tabela Oracle. ... é bem profundo, eu sei, mas a etapa que está me segurando agora é colocar os dados em um DataFrame .... meu dicionário, por algum motivo, tem uma chave e todos os dados estão em valores, por isso é difícil tentando colocá-lo perfeitamente em linhas e colunas ..
theprowler
118

Você pode usar o jsonmódulo para isso. A dumpsfunção neste módulo converte um objeto JSON em uma string formatada corretamente, que você pode imprimir.

import json

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

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

A saída parece

{
    "UMA": {
        "cor": 2,
        "velocidade": 70
    }
    "B": {
        "cor": 3,
        "velocidade": 60
    }
}

A documentação também especifica várias opções úteis para esse método.

kchak
fonte
2
true, o conteúdo do dict deve ser serializado em json; no entanto, a saída fornecida aqui é muito mais limpa (por exemplo, legível por humanos) do que a saída produzida pelo pprint.PrettyPrinter. especificamente na área de recuo consistente e descarte de prefixos de string, como u'foo '.
Buffalo Rabor
Eu faço print(json.dumps(cars, indent=4, ensure_ascii=False))porque, caso contrário, caracteres não ASCII são ilegíveis.
Boris
85

Uma solução mais generalizada que lida com ditados e listas aninhados arbitrariamente e profundamente seria:

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

Isso produz a saída:

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

Encontrei uma necessidade semelhante e desenvolvi uma função mais robusta como exercício para mim. Estou incluindo aqui caso seja de valor para outro. Ao executar o nosetest, também achei útil poder especificar o fluxo de saída na chamada para que o sys.stderr pudesse ser usado.

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 função, a saída do OP fica assim:

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

que eu pessoalmente achei mais útil e descritivo.

Dado o exemplo um pouco menos trivial de:

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

A solução solicitada pelo OP produz o seguinte:

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

considerando que a versão 'aprimorada' gera isso:

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

Espero que isso ofereça algum valor para a próxima pessoa que procura esse tipo de funcionalidade.

MrWonderful
fonte
11
E se o formato não for muito rigoroso, também é possível usar 'print json.dumps (obj, indent = 3)'. Isso dá uma representação razoável da maioria das estruturas, embora ele não choke (em meu ambiente) no meu exemplo menos trivial devido ao uso de uma tupla como uma chave ...
MrWonderful
7
Por que não usar pprint.pprint()aqui, então?
Martijn Pieters
1
quase fez um criador de JSON, não?
precisa saber é o seguinte
30

Você tem uma estrutura aninhada, portanto, você também precisa formatar o dicionário aninhado:

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

Isso imprime:

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

pprint.pprint() é uma boa ferramenta para este trabalho:

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

Isso funcionará se você souber que a árvore possui apenas dois níveis:

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

Verifique a seguinte linha:

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

Resultado:

A
speed : 70
color : 2
B
speed : 60
color : 3
kenorb
fonte
Bom, mas tentei convertê-lo para usá-lo sys.modules, mas falhei. Quer tentar?
not2qubit
4

Eu prefiro a formatação limpa de yaml:

import yaml
yaml.dump(cars)

resultado:

A:
  color: 2
  speed: 70
B:
  color: 3
  speed: 60
gizzmole
fonte
Você tem que pip install PyYAMLprimeiro.
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
fonte
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
TheManHimself
fonte
0

Aqui está a minha solução para o problema. Eu acho que é semelhante na abordagem, mas um pouco mais simples do que algumas das outras respostas. Ele também permite um número arbitrário de subdicionários e parece funcionar para qualquer tipo de dados (eu até testei em um dicionário que tinha funções 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)
rocksNwaves
fonte
-1

Modificando o 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
fonte
1
O que você modificou? Qual é o resultado?
Andreas Haferburg