Czytelnie wydrukuj pythonową dict () posortowaną według klucza

82

Chciałbym wydrukować słownik Pythona do pliku za pomocą PrettyPrinter (dla czytelności dla ludzi), ale słownik powinien być posortowany według klucza w pliku wyjściowym, aby jeszcze bardziej poprawić czytelność. Więc:

mydict = {'a':1, 'b':2, 'c':3}
pprint(mydict)

aktualnie drukuje do

{'b':2,
 'c':3,
 'a':1}

Chciałbym, aby słownik PrettyPrint został wydrukowany, posortowany według klucza, np.

{'a':1,
 'b':2,
 'c':3}

Jaki jest najlepszy sposób, aby to zrobić?


źródło
Okazuje się, że pprint sortuje już według klucza. Powinienem był to dokładniej sprawdzić.

Odpowiedzi:

94

Właściwie wydaje się, że pprint sortuje klucze pod python2.5

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3}
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}

Ale nie zawsze pod Pythonem 2.4

>>> from pprint import pprint
>>> mydict = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
>>> pprint(mydict)
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
>>> d = dict(zip("kjihgfedcba",range(11)))
>>> pprint(d)
{'a': 10,
 'b': 9,
 'c': 8,
 'd': 7,
 'e': 6,
 'f': 5,
 'g': 4,
 'h': 3,
 'i': 2,
 'j': 1,
 'k': 0}
>>> 

Czytając kod źródłowy pprint.py (2.5) sortuje słownik używając

items = object.items()
items.sort()

dla multilinii lub dla jednej linii

for k, v in sorted(object.items()):

zanim spróbuje cokolwiek wydrukować, więc jeśli twój słownik sortuje poprawnie w ten sposób, powinien poprawnie wydrukować. W 2.4 brakuje drugiej sortowanej () (wtedy nie istniała), więc obiekty drukowane w jednej linii nie będą sortowane.

Wydaje się więc, że odpowiedzią jest użycie pythona2.5, chociaż nie wyjaśnia to do końca wyniku pytania.

Aktualizacja Python3

Dość wypisuj według posortowanych kluczy (lambda x: x [0]):

for key, value in sorted(dict_example.items(), key=lambda x: x[0]): 
    print("{} : {}".format(key, value))

Całkiem wypisz według posortowanych wartości (lambda x: x [1]):

for key, value in sorted(dict_example.items(), key=lambda x: x[1]): 
    print("{} : {}".format(key, value))
Nick Craig-Wood
źródło
Rozwiązanie wyrażenia lambda w Pythonie 3 jest sprytne. Dla jasności uważam, że (?) keyW for key, value in ...jest niezależne od keyw, key=lambda ...jak to działa, for k,v in sorted(token_dict.items(), key=lambda x: x[0])ale for k,v in sorted(token_dict.items(), k=lambda x: x[0])generuje błąd.
Victoria Stuart,
19

Inna alternatywa:

>>> mydict = {'a':1, 'b':2, 'c':3}
>>> import json

Następnie z pythonem2:

>>> print json.dumps(mydict, indent=4, sort_keys=True) # python 2
{
    "a": 1, 
    "b": 2, 
    "c": 3
}

lub z Pythonem 3:

>>> print(json.dumps(mydict, indent=4, sort_keys=True)) # python 3
{
    "a": 1, 
    "b": 2, 
    "c": 3
}
Skippy le Grand Gourou
źródło
14

Prosty sposób na wydrukowanie posortowanej zawartości słownika w Pythonie 3:

>>> dict_example = {'c': 1, 'b': 2, 'a': 3}
>>> for key, value in sorted(dict_example.items()):
...   print("{} : {}".format(key, value))
... 
a : 3
b : 2
c : 1

Wyrażenie dict_example.items()zwraca krotki, które można następnie posortować według sorted():

>>> dict_example.items()
dict_items([('c', 1), ('b', 2), ('a', 3)])
>>> sorted(dict_example.items())
[('a', 3), ('b', 2), ('c', 1)]

Poniżej znajduje się przykład ładnego drukowania posortowanej zawartości wartości słownika Pythona.

for key, value in sorted(dict_example.items(), key=lambda d_values: d_values[1]): 
    print("{} : {}".format(key, value))
Zweedeend
źródło
Bardzo dobrze. Oto przykład, aby ładnie wydrukować posortowaną zawartość wartości słownika Pythona:for key, value in sorted(dict_example.items(), key=lambda d_items: d_items[1]): print("{} : {}".format(key, value))
Scott Skiles,
1
@ScottSkiles, powinieneś edytować odpowiedź i dodać do niej swój przykład - myślę, że pomogłoby to przyszłym czytelnikom
redbeam_
13

pprintModuł Pythona w rzeczywistości sortuje już słowniki według klucza. W wersjach wcześniejszych niż Python 2.5 sortowanie było uruchamiane tylko w słownikach, których ładnie wydrukowana reprezentacja obejmowała wiele wierszy, ale w wersjach 2.5.X i 2.6.X wszystkie słowniki są sortowane.

Ogólnie jednak, jeśli piszesz struktury danych w pliku i chcesz, aby były czytelne dla człowieka i możliwe do zapisu, możesz rozważyć użycie alternatywnego formatu, takiego jak YAML lub JSON. O ile użytkownicy sami nie są programistami, utrzymywanie przez nich konfiguracji lub stanu aplikacji zrzucanych pprinti ładowanych przez evalmoże być frustrującym i podatnym na błędy zadaniem.

rcoder
źródło
2
btw, ast.literal_eval("{'a': 0, 'b': 1, 2: 'c'}")-> {2: 'c', 'a': 0, 'b': 1}więc nie ma potrzeby być bezbożni eval.
jfs
tak i najwyraźniej pprint nie oferuje sposobu na wyłączenie tego zachowania. Zmarnowano godzinę lub dwie, próbując dowiedzieć się, dlaczego niektóre przykładowe dane raportu pprint są sortowane według kluczy.
Samantha Atkins
12

Napisałem następującą funkcję, aby wydrukować dykty, listy i krotki w bardziej czytelnym formacie:

def printplus(obj):
    """
    Pretty-prints the object passed in.

    """
    # Dict
    if isinstance(obj, dict):
        for k, v in sorted(obj.items()):
            print u'{0}: {1}'.format(k, v)

    # List or tuple            
    elif isinstance(obj, list) or isinstance(obj, tuple):
        for x in obj:
            print x

    # Other
    else:
        print obj

Przykładowe użycie w iPythonie:

>>> dict_example = {'c': 1, 'b': 2, 'a': 3}
>>> printplus(dict_example)
a: 3
b: 2
c: 1

>>> tuple_example = ((1, 2), (3, 4), (5, 6), (7, 8))
>>> printplus(tuple_example)
(1, 2)
(3, 4)
(5, 6)
(7, 8)
Scott Foubister
źródło
5

Miałem ten sam problem co ty. Użyłem pętli for z posortowaną funkcją przekazaną do słownika w następujący sposób:

for item in sorted(mydict):
    print(item)
kurczak
źródło
4

Możesz trochę zmienić ten dyktando, aby upewnić się, że (ponieważ dykty nie są posortowane wewnętrznie), np

pprint([(key, mydict[key]) for key in sorted(mydict.keys())])
Cat Plus Plus
źródło
0

Kolejny krótki oneliner:

mydict = {'c': 1, 'b': 2, 'a': 3}
print(*sorted(mydict.items()), sep='\n')
Friedrich
źródło