Hay una función existente que termina en la siguiente, donde d es un diccionario:

return d.iteritems()

que devuelve un sin clasificar iterador para un determinado diccionario. Me gustaría volver un iterador que pasa a través de los elementos ordenados por clave. ¿Cómo puedo hacer eso?

InformationsquelleAutor mike | 2008-12-12

10 Comentarios

  1. 166

    No ha probado muy a fondo, pero funciona en Python 2.5.2.

    >>> d = {"x":2, "h":15, "a":2222}
    >>> it = iter(sorted(d.iteritems()))
    >>> it.next()
    ('a', 2222)
    >>> it.next()
    ('h', 15)
    >>> it.next()
    ('x', 2)
    >>>

    Si usted está acostumbrado a hacer for key, value in d.iteritems(): ... en lugar de iteradores, este seguirá funcionando con la solución anterior

    >>> d = {"x":2, "h":15, "a":2222}
    >>> for key, value in sorted(d.iteritems()):
    >>>     print(key, value)
    ('a', 2222)
    ('h', 15)
    ('x', 2)
    >>>

    Con Python 3.x, el uso de d.items() en lugar de d.iteritems() para devolver un iterador.

    • uso .items() en lugar de iteritems(): como @Claudiu dijo, iteritems no funciona para Python 3.x, pero items() está disponible desde Python 2.6.
    • Esto no es obvio. De hecho, items() crea una lista y por lo tanto el uso de la memoria, mientras que iteritems() esencialmente no uso de la memoria. Qué usar en su mayoría dependen del tamaño del diccionario. Además, el automático de Python 2 a Python 3 de la herramienta de conversión (2to3) automáticamente se encarga de la conversión de iteritems() a items(), así que no hay necesidad de preocuparse acerca de esto.
    • Es posible optimizar en caso de que ambos getitem y se ordenan de la iteración son muy frecuentemente se necesita?
    • el uso de un collections.OrderedDict luego de ordenar una vez & obtener elementos en orden de siempre.
    • Pero @EOL, incluso si iteritems() no hace uso de la memoria, todo lo que debe ser tirado en la memoria para sorted(), así que no hay diferencia entre el uso de items() y iteritems() aquí la memoria del sabio.
    • Si bien es cierto que todos los elementos deben estar tirado en la memoria, son almacenado dos veces con items() (en la lista devuelta por items(), y en la lista ordenada) y sólo una vez con iteritems() (en la lista ordenada solamente).

  2. 80

    Utilizar el ordenados() función:

    return sorted(dict.iteritems())

    Si quieres un real iterador sobre los resultados ordenados, ya que sorted() devuelve una lista, utilice:

    return iter(sorted(dict.iteritems()))
    • Que falla para mí: <tipo de excepciones.TypeError’>: iter() devuelve no-iterador de tipo ‘lista’
    • Eso es probablemente porque el uso de «dict» como el nombre de la variable. «dict» es en realidad el nombre del tipo de diccionarios. Sólo use otro nombre como «mydict» aquí y listo.
    • Todavía no está trabajando. Están ordenadas positivas() devuelve otro iterador, en contraposición a una lista normal?
    • ¿dónde y cuándo se trata de una excepción de ocurrir? se puede iterar sobre una lista sin problema
    • podría fallar si estuviera llamando a el .método next() en la lista, que funcionaría en el iterador
    • bueno, yo de alguna manera se que problema tan trivial 😉
    • De acuerdo, hop. Creo que no me vuelvas a llamar .next (), excepto cuando omita las líneas en los archivos. Nuestro iter(ordenados(dict.iteritems())) solución termina haciendo una copia de toda la dict en la memoria en el «ordenada» de la etapa de todos modos, por lo que el principal iterador beneficio parece perdido 🙂
    • Se tiene que enchufar en una API que espera un iterador.

  3. 39

    Un diccionario de claves se almacenan en una tabla hash, así que es su «orden natural», es decir, pseudo-aleatorios. Cualquier otro pedido es un concepto de consumidor, de la dict.

    ordenada() siempre devuelve una lista, no un diccionario. Si le pasas un dict.los elementos() (que genera una lista de tuplas), devuelve una lista de tuplas [(k1,v1), (k2,v2), …], que puede ser utilizado en un bucle de una manera muy parecida a la de un diccionario, pero no es de todos modos un dict!

    foo = {
        'a':    1,
        'b':    2,
        'c':    3,
        }
    
    print foo
    >>> {'a': 1, 'c': 3, 'b': 2}
    
    print foo.items()
    >>> [('a', 1), ('c', 3), ('b', 2)]
    
    print sorted(foo.items())
    >>> [('a', 1), ('b', 2), ('c', 3)]

    Los siguientes siente como un diccionario en un bucle, pero no lo es, es una lista de tuplas de ser desempaquetados en k,v:

    for k,v in sorted(foo.items()):
        print k, v

    Aproximadamente equivalente a:

    for k in sorted(foo.keys()):
        print k, foo[k]
    • Bueno, pero yo no quiero un Diccionario o en una Lista, quiero un Iterador. ¿Cómo puedo convertir en un Iterador?
    • sorted(foo.keys()) es mejor como el equivalente sorted(foo), ya que los diccionarios de devolver sus llaves cuando iterado (con la ventaja de no ser obligados a crear la foo.keys() intermedio de la lista, tal vez, dependiendo de cómo sorted() se implementa para iterables).
    • Se preguntan que es mejor para la velocidad y/o la memoria k in sorted(foo.keys()): que tira las llaves o for k,v in sorted(foo.items()): que devuelve una copia del diccionario de la lista de pares me imagino sorted(foo.keys())
    • La mejor manera de responder a la vez pregunta es con el Python timeit módulo.
    • Rowell gracias a que ni siquiera saben acerca de timeit voy a darle una oportunidad.
    • Lo hice correr varias pruebas tuvo que volver a 250k y se encontró sin un claro ganador, aunque fue capaz de ejecutar en un millón y por lo que puedo ver voy a utilizar k in sorted(foo.keys()): ver ->github.com/CrandellWS/Udacity-Nanodegree/commit/…
    • Me alegro de que se útil para usted. Otras cosas a considerar antes de llegar demasiado lejos en la Optimización de la Tierra incluyen: ¿Cómo a menudo es esta rutina de llamada? Si la entrada cambia con poca frecuencia puede usted almacenar en caché el resultado? Etc. Real de la prueba y la sincronización son la única manera de responder a esa eterna pregunta: «Es 11pm. ¿Sabes dónde su el programa está gastando su tiempo?»
    • Cuando he estado usando dicts en python 3, sin embargo, y lo que yo llamo for k,v in d.items(), siempre devuelve las teclas en el orden que se coloca. Es esto algo que se puede contar?
    • Respuesta Corta: No. Un diccionario es una matriz con la clave real de ser un hash el valor de la llave de serie. Aunque algunas implementaciones pueden ser bastante predecible, y algunos pueden incluso hacer de este contrato, cuento con nada cuando se trata de hash de realizar el pedido. Consulte este post para más información sobre 3.6+ comportamiento. En la nota, en particular, la primera respuesta.

  4. 30

    De Greg respuesta es correcta. Tenga en cuenta que en Python 3.0 tendrás que hacer

    sorted(dict.items())

    como iteritems se ha ido.

    • Que falla para mí: <tipo de excepciones.TypeError’>: iter() devuelve no-iterador de tipo ‘lista’
    • «No hacer uso de los coches porque en el futuro vamos a tener hoverboards»
  5. 6

    Ahora puede utilizar OrderedDict en Python 2.7 así:

    >>> from collections import OrderedDict
    >>> d = OrderedDict([('first', 1),
    ...                  ('second', 2),
    ...                  ('third', 3)])
    >>> d.items()
    [('first', 1), ('second', 2), ('third', 3)]

    Aquí tienes la qué hay de nuevo página para la versión 2.7 y la OrderedDict API.

  6. 5

    En general, uno puede ordenar un diccionario como:

    for k in sorted(d):
        print k, d[k]

    Para el caso específico de la cuestión, teniendo una «gota en el reemplazo» para d.iteritems(), agregar una función como:

    def sortdict(d, **opts):
        # **opts so any currently supported sorted() options can be passed
        for k in sorted(d, **opts):
            yield k, d[k]

    y para el final de la línea de cambios de

    return dict.iteritems()

    a

    return sortdict(dict)

    o

    return sortdict(dict, reverse = True)
  7. 4
    >>> import heapq
    >>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
    >>> def iter_sorted(d):
            keys = list(d)
            heapq.heapify(keys) # Transforms to heap in O(N) time
            while keys:
                k = heapq.heappop(keys) # takes O(log n) time
                yield (k, d[k])
    
    
    >>> i = iter_sorted(d)
    >>> for x in i:
            print x
    
    
    ('a', 4)
    ('b', 9)
    ('c', 2)
    ('d', 8)

    Este método tiene un O(N log N) ordenar, sin embargo, después de un corto lineal heapify, que los rendimientos de los elementos en orden de como va, lo que es teóricamente más eficiente cuando no siempre se necesita la totalidad de la lista.

  8. 3

    ordenados devuelve una lista, de ahí su error cuando intenta iterar sobre ella,
    pero porque no se puede pedir un diccionario, tendrá que lidiar con una lista.

    No tengo idea de lo que el contexto más amplio de tu código, pero podría intentar agregar un
    iterador de la lista resultante.
    como este tal vez?:

    return iter(sorted(dict.iteritems()))

    de curso usted estará volviendo tuplas ahora porque ordenados volvió su dict en una lista de tuplas

    ex:
    dicen que su dict fue:
    {'a':1,'c':3,'b':2}
    ordenan la convierte en una lista:

    [('a',1),('b',2),('c',3)]

    así que cuando usted realmente iterar sobre la lista de volver (en este ejemplo) es una tupla
    compuesto de una cadena y un entero, pero al menos usted será capaz de recorrer más de él.

  9. 2

    Asumiendo que usted está utilizando CPython 2.x, y tienen una gran diccionario mydict, a continuación, utilizando ordenados(mydict) va a ser lento porque ordenados construye una lista ordenada de las claves de mydict.

    Que en caso de que usted puede ser que desee mirar a mi ordereddict paquete que incluye una implementación en C de sorteddict en C. Especialmente si usted tiene que ir en la lista ordenada de las teclas varias veces en diferentes etapas (es decir. número de elementos) de los diccionarios de toda la vida.

    http://anthon.home.xs4all.nl/Python/ordereddict/

Dejar respuesta

Please enter your comment!
Please enter your name here