Imprima de forma legible un dict () de python ordenado por clave

81

Me gustaría imprimir un diccionario de Python en un archivo usando PrettyPrinter (para legibilidad humana) pero ordenar el diccionario por clave en el archivo de salida para mejorar aún más la legibilidad. Entonces:

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

actualmente imprime a

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

Me gustaría PrettyPrint el diccionario, pero lo imprimo ordenado por clave, por ejemplo.

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

¿Cuál es la mejor manera de hacer esto?


fuente
Resulta que pprint ya ordena por clave. Debería haberlo comprobado con más cuidado.

Respuestas:

94

En realidad, pprint parece ordenar las claves para usted en 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}

Pero no siempre bajo 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}
>>> 

Al leer el código fuente de pprint.py (2.5), ordena el diccionario usando

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

para multilínea o esto para una sola línea

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

antes de que intente imprimir algo, por lo que si su diccionario se ordena correctamente, entonces debería imprimir correctamente. En 2.4, falta el segundo sorted () (no existía entonces) por lo que los objetos impresos en una sola línea no se ordenarán.

Entonces, la respuesta parece ser usar python2.5, aunque esto no explica del todo su resultado en la pregunta.

Actualización de Python3

Impresión bonita por claves ordenadas (lambda x: x [0]):

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

Impresión bonita por valores ordenados (lambda x: x [1]):

for key, value in sorted(dict_example.items(), key=lambda x: x[1]): 
    print("{} : {}".format(key, value))
Nick Craig-Wood
fuente
La solución de expresión lambda de Python 3 es elegante. Para mayor claridad, creo (?) keyEn for key, value in ...es independiente de keyen key=lambda ...ya que esto funciona, for k,v in sorted(token_dict.items(), key=lambda x: x[0])pero for k,v in sorted(token_dict.items(), k=lambda x: x[0])arroja un error.
Victoria Stuart
18

Otra alternativa:

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

Luego con python2:

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

o con python 3:

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

Una forma fácil de imprimir el contenido ordenado del diccionario, en 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

La expresión dict_example.items()devuelve tuplas, que luego se pueden ordenar por sorted():

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

A continuación se muestra un ejemplo para imprimir de forma bonita el contenido ordenado de los valores de un diccionario de Python.

for key, value in sorted(dict_example.items(), key=lambda d_values: d_values[1]): 
    print("{} : {}".format(key, value))
Zweedeend
fuente
Muy agradable. Aquí hay un ejemplo para imprimir bastante el contenido ordenado de los valores de un diccionario de Python:for key, value in sorted(dict_example.items(), key=lambda d_items: d_items[1]): print("{} : {}".format(key, value))
Scott Skiles
1
@ScottSkiles, debe editar la respuesta y agregarle su ejemplo; creo que ayudaría a los futuros lectores
redbeam_
13

El pprintmódulo de Python ya ordena los diccionarios por clave. En las versiones anteriores a Python 2.5, la clasificación solo se activaba en los diccionarios cuya representación impresa en forma bonita abarcaba varias líneas, pero en 2.5.X y 2.6.X, todos los diccionarios están ordenados.

Sin embargo, en general, si está escribiendo estructuras de datos en un archivo y desea que las personas puedan leerlas y escribirlas, es posible que desee considerar el uso de un formato alternativo como YAML o JSON. A menos que los usuarios sean ellos mismos programadores, hacer que mantengan la configuración o el estado de la aplicación descargado pprinty cargado mediante evalpuede ser una tarea frustrante y propensa a errores.

codificador
fuente
2
por cierto, ast.literal_eval("{'a': 0, 'b': 1, 2: 'c'}")-> {2: 'c', 'a': 0, 'b': 1}así que no hay necesidad de impíos eval.
jfs
sí y aparentemente pprint no ofrece una forma de desactivar este comportamiento. Perdí una hora o dos tratando de averiguar por qué algunos datos de informes de muestra de pprint se ordenaban en claves.
Samantha Atkins
12

Escribí la siguiente función para imprimir dictados, listas y tuplas en un formato más legible:

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

Ejemplo de uso en 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)
Scott Foubister
fuente
5

Tuve el mismo problema que tuviste. Usé un bucle for con la función ordenada pasando en el diccionario así:

for item in sorted(mydict):
    print(item)
pez pollo
fuente
4

Puede transformar un poco este dictado para asegurarse de que (dado que los dictados no se mantienen ordenados internamente), p. Ej.

pprint([(key, mydict[key]) for key in sorted(mydict.keys())])
Gato Plus Plus
fuente
0

Otro delineador corto:

mydict = {'c': 1, 'b': 2, 'a': 3}
print(*sorted(mydict.items()), sep='\n')
Friedrich
fuente