Зрозуміло роздрукуйте python dict (), відсортований за ключем


82

Я хотів би надрукувати словник python у файлі за допомогою PrettyPrinter (для зручності читання), але нехай сортується словник за ключем у вихідному файлі для подальшого покращення читабельності. Так:

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

в даний час друкує в

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

Я хотів би PrettyPrint словник, але роздрукувати його, відсортований за ключем, наприклад.

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

Який найкращий спосіб це зробити?

python 

Виходить, pprint вже сортується за ключем. Потрібно було перевірити це більш ретельно.

Відповіді:


94

Насправді pprint, здається, сортує ключі для вас під 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}

Але не завжди під python 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}
>>> 

Читаючи вихідний код pprint.py (2.5), він сортує словник за допомогою

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

для багаторядкової або для однорядкової

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

перед тим, як він спробує що-небудь надрукувати, тому, якщо ваш словник правильно сортує, то він повинен надрукувати належним чином. У 2.4 друга sorted () відсутня (тоді її ще не існувало), тому об'єкти, надруковані в одному рядку, не будуть сортуватися.

Отже, відповідь полягає у використанні python2.5, хоча це не зовсім пояснює ваші результати у питанні.

Оновлення Python3

Досить друк за відсортованими клавішами (лямбда x: x [0]):

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

Досить друк за відсортованими значеннями (лямбда x: x [1]):

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

Розв’язання лямбда-виразів Python 3 є гладким. Для ясності, я вважаю (?) keyIn for key, value in ...не залежить від keyin, key=lambda ...оскільки це працює, for k,v in sorted(token_dict.items(), key=lambda x: x[0])але for k,v in sorted(token_dict.items(), k=lambda x: x[0])видає помилку.
Вікторія Стюарт

19

Інша альтернатива:

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

Потім з python2:

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

або з python 3:

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

14

Простий спосіб роздрукувати відсортований вміст словника в Python 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

Вираз dict_example.items()повертає кортежі, які потім можна відсортувати за sorted():

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

Нижче наведено приклад гарного друку відсортованого вмісту значень словника Python.

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

Дуже мило. Ось приклад красивого друку відсортованого вмісту значень словника Python:for key, value in sorted(dict_example.items(), key=lambda d_items: d_items[1]): print("{} : {}".format(key, value))
Скотт Скілз

1
@ScottSkiles ти повинен відредагувати відповідь і додати до неї свій приклад - я думаю, це допомогло б майбутнім читачам
redbeam_

13

Модуль Python pprintнасправді вже сортує словники за ключами. У версіях до Python 2.5 сортування ініціювалось лише у словниках, чиє надруковане подання охоплювало кілька рядків, але в 2.5.X та 2.6.X усі словники сортувались.

Як правило, якщо ви пишете структури даних у файл і хочете, щоб вони були зручні для читання та для запису, ви можете розглянути можливість використання іншого формату, такого як YAML або JSON. Якщо ваші користувачі самі не є програмістами, їх підтримка конфігурації або стану додатків, які скидаються через pprintі завантажуються через, evalможе бути неприємним завданням, яке спричиняє помилки.


2
до речі, ast.literal_eval("{'a': 0, 'b': 1, 2: 'c'}")-> {2: 'c', 'a': 0, 'b': 1}тому немає потреби в безбожних eval.
jfs

так, мабуть, pprint не пропонує способу вимкнути цю поведінку. Даремно витратив годину чи дві, намагаючись зрозуміти, чому деякі зразки даних зразків відбитків сортуються за ключами.
Саманта

12

Я написав наступну функцію для друку диктовок, списків і кортежів у більш читаному форматі:

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

Приклад використання в iPython:

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

У мене була та сама проблема, що і у вас. Я використав цикл for з відсортованою функцією, що передається у словнику так:

for item in sorted(mydict):
    print(item)

4

Ви можете трохи перетворити цей дикт, щоб переконатися, що (оскільки диктовки не сортуються внутрішньо), наприклад

pprint([(key, mydict[key]) for key in sorted(mydict.keys())])

0

Ще один короткий лайнер:

mydict = {'c': 1, 'b': 2, 'a': 3}
print(*sorted(mydict.items()), sep='\n')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.