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

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

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.


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.


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

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

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

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

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

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

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

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

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)

-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

1
Co zmodyfikowałeś? Jaki jest wynik?
Andreas Haferburg
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.