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

python 

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

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
}

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

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.


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)

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)

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

0

Kolejny krótki oneliner:

mydict = {'c': 1, 'b': 2, 'a': 3}
print(*sorted(mydict.items()), sep='\n')
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.