Jak wydrukować słownik wiersz po wierszu w Pythonie?

166

To jest słownik

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

Korzystanie z tego for loop

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

Drukuje następujące informacje:

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

Ale chcę, aby program wydrukował to w ten sposób:

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

Właśnie zacząłem się uczyć słowników, więc nie wiem, jak to zrobić.

Jett
źródło

Odpowiedzi:

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

wynik:

A
color : 2
speed : 70
B
color : 3
speed : 60
namit
źródło
12
Wiem, że to jest stare, ale pomyślałem, że warto wspomnieć, że to nie działa, jeśli samochody [x] są liczbami całkowitymi. To nie jest to, o co prosił OP, więc mówię to każdemu, kto się na to natknie, zakładając, że jest to ogólne rozwiązanie.
Darrel Holt
@DarrelHolt Czy wiesz, jak to działa z liczbami całkowitymi? Ponieważ to jest problem, z którym obecnie się
zmagam
@theprowler Najbliższe odtworzenie problemu jest to, czy cars = {1:4, 2:5}to cars[x]jest liczbą całkowitą odwzorowaną na klucz, xa nie zestawem odwzorowanym na klucz x. W takim przypadku nie musisz używać for y in cars[x]:linii, ponieważ pobierasz tylko jedną wartość, chyba że używasz czegoś takiego jak lista lub zestaw liczb całkowitych, wtedy powinno działać. Przepraszam, minęło już kilka miesięcy, więc nie pamiętam do końca, jak doszedłem do konkluzji mojego poprzedniego komentarza. Możesz wysłać mi swój kod, a ja zobaczę, czy jestem w stanie pomóc.
Darrel Holt
Hmm. Myślę, że mój problem jest jeszcze gorszy. Zasadniczo przeanalizowałem niektóre dane z tabeli HTML i zdarzyło mi się przechowywać je w słowniku, a teraz próbuję pobrać te dane ze słownika i umieścić je w DataFrame, zanim wyeksportuję je wszystkie do tabeli Oracle. ... jest dość dogłębny, wiem, ale krok, który mnie teraz powstrzymuje, to umieszczenie danych w DataFrame ... mój słownik z jakiegoś powodu ma jeden klucz i wszystkie dane są w wartościach, więc jest to trudne próbując umieścić to starannie w rzędach i kolumnach ...
theprowler
118

Możesz użyć jsondo tego modułu. dumpsFunkcji w tym module konwertuje obiekt JSON do prawidłowo sformatowany ciąg znaków, które można następnie wydrukować.

import json

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

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

Wynik wygląda jak

{
    „A”: {
        "kolor": 2,
        „prędkość”: 70
    },
    "B": {
        "kolor": 3,
        „prędkość”: 60
    }
}

Dokumentacja określa również kilka przydatnych opcji dla tej metody.

kchak
źródło
2
prawda, zawartość dyktowania musi być możliwa do serializacji do json, jednak dane wyjściowe podane tutaj są znacznie czystsze (np. czytelne dla człowieka) niż wyjście utworzone przez pprint.PrettyPrinter. szczególnie w obszarze spójnego wcięcia i odrzucania przedrostków ciągów, takich jak u'foo '.
Buffalo Rabor
Robię to, print(json.dumps(cars, indent=4, ensure_ascii=False))ponieważ w przeciwnym razie znaki spoza ASCII są nieczytelne.
Boris
85

Bardziej uogólnionym rozwiązaniem, które obsługuje dowolnie głęboko zagnieżdżone dykty i listy, byłoby:

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

To daje wynik:

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

Wpadłem na podobną potrzebę i rozwinąłem bardziej solidną funkcję jako ćwiczenie dla siebie. Dołączam go tutaj na wypadek, gdyby miał znaczenie dla innego. Podczas uruchamiania programu nosetest okazało się również pomocne, aby móc określić strumień wyjściowy w wywołaniu, aby zamiast tego można było użyć 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)

Korzystając z tej funkcji, wyjście OP wygląda następująco:

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

które osobiście uważam za bardziej przydatne i opisowe.

Biorąc pod uwagę nieco mniej trywialny przykład:

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

Żądane rozwiązanie OP daje to:

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

mając na uwadze, że wersja `` ulepszona '' daje to:

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

Mam nadzieję, że zapewni to pewną wartość następnej osobie szukającej tego typu funkcjonalności.

MrWonderful
źródło
11
A jeśli format nie jest zbyt ścisły, można również użyć polecenia „print json.dumps (obj, indent = 3)”. Daje to rozsądną reprezentację większości struktur, chociaż dławi się (w moim środowisku) moim mniej banalnym przykładem z powodu użycia krotki jako klucza ...
MrWonderful
7
Dlaczego więc nie użyć pprint.pprint()tutaj?
Martijn Pieters
1
prawie stworzyłeś JSON, prawda?
user2007447
30

Masz strukturę zagnieżdżoną, więc musisz również sformatować zagnieżdżony słownik:

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

To drukuje:

A
color : 2
speed : 70
B
color : 3
speed : 60
Martijn Pieters
źródło
28

pprint.pprint() jest dobrym narzędziem do tej pracy:

>>> 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
źródło
6
for car,info in cars.items():
    print(car)
    for key,value in info.items():
        print(key, ":", value)
Scott Olson
źródło
4

To zadziała, jeśli wiesz, że drzewo ma tylko dwa poziomy:

for k1 in cars:
    print(k1)
    d = cars[k1]
    for k2 in d
        print(k2, ':', d[k2])
Benjamin Hodgson
źródło
4

Sprawdź następującą jedną linijkę:

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

Wynik:

A
speed : 70
color : 2
B
speed : 60
color : 3
kenorb
źródło
Niezły, ale próbowałem go przekonwertować, aby używać tego z sys.modules, ale nie udało mi się. Chcesz spróbować?
not2qubit
4

Wolę czyste formatowanie yaml:

import yaml
yaml.dump(cars)

wynik:

A:
  color: 2
  speed: 70
B:
  color: 3
  speed: 60
gizzmole
źródło
Musisz pip install PyYAMLnajpierw.
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
źródło
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
źródło
0

Oto moje rozwiązanie problemu. Myślę, że podejście jest podobne, ale trochę prostsze niż niektóre inne odpowiedzi. Pozwala również na dowolną liczbę podsłówników i wydaje się działać dla dowolnego typu danych (testowałem to nawet na słowniku, który miał funkcje jako wartości):

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)
skałyNwaves
źródło
-1

Modyfikowanie kodu 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
źródło
1
Co zmodyfikowałeś? Jaki jest wynik?
Andreas Haferburg