Imagine que usted tiene:

keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']

¿Cuál es la forma más sencilla de producir el siguiente diccionario?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
InformationsquelleAutor Guido | 2008-10-16

14 Comentarios

  1. 1850

    Como este:

    >>> keys = ['a', 'b', 'c']
    >>> values = [1, 2, 3]
    >>> dictionary = dict(zip(keys, values))
    >>> print(dictionary)
    {'a': 1, 'b': 2, 'c': 3}

    Los pares dict constructor y zip función son increíblemente útil: https://docs.python.org/3/library/functions.html#func-dict

    • Vale la pena señalar que dictionary = {zip(keys, values)} no funciona. Usted tiene que declarar explícitamente como dict(...)
    • No sé por qué puede esperar que, @FernandoWittmann. {thing} es azúcar sintáctico para la construcción de un set() que contiene uno de los elementos. {*iterable} es azúcar sintáctico para la construcción de un set que contiene varios elementos. {k:v} o {**mapping} será la construcción de un dict, pero eso es sintácticamente muy distinta.
    • Gracias por el comentario de Dan. Estás en lo correcto. Mi confusión ocurrió porque yo normalmente uso la sintaxis {} de los diccionarios. De hecho, si tratamos de type({}) la salida es dict. Pero, de hecho, si tratamos de type({thing}) entonces la salida es set.
  2. 122

    Intente esto:

    >>> import itertools
    >>> keys = ('name', 'age', 'food')
    >>> values = ('Monty', 42, 'spam')
    >>> adict = dict(itertools.izip(keys,values))
    >>> adict
    {'food': 'spam', 'age': 42, 'name': 'Monty'}

    En Python 2, también es más económico en el consumo de memoria en comparación con zip.

  3. 115

    Imagine que usted tiene:

    keys = ('name', 'age', 'food')
    values = ('Monty', 42, 'spam')

    ¿Cuál es la forma más sencilla de producir el siguiente diccionario ?

    dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

    Más eficiente – Python 2.7 y 3, dict comprensión:

    Una posible mejora en el uso de la dict constructor es el uso de la sintaxis nativa de un diccionario de comprensión (no una lista de comprensión, como otros han puesto erróneamente es):

    new_dict = {k: v for k, v in zip(keys, values)}

    En Python 2, zip devuelve una lista, para evitar la creación innecesaria de la lista, utilice izip lugar (con el alias zip puede reducir los cambios de código cuando se mueve a Python 3).

    from itertools import izip as zip

    De modo que sigue:

    new_dict = {k: v for k, v in zip(keys, values)}

    Python 2, ideal para <= 2.6

    izip de itertools se convierte en zip en Python 3. izip es mejor que el zip para Python 2 (debido a que se evita la innecesaria creación de listas), y es ideal para 2.6 o a continuación:

    from itertools import izip
    new_dict = dict(izip(keys, values))

    Python 3

    En Python 3, zip se hace la misma función que estaba en el itertools módulo, por lo que simplemente es:

    new_dict = dict(zip(keys, values))

    Un diccionario de comprensión sería más eficiente aunque (ver revisión de desempeño al final de esta respuesta).

    Resultado para todos los casos:

    En todos los casos:

    >>> new_dict
    {'age': 42, 'name': 'Monty', 'food': 'spam'}

    Explicación:

    Si nos fijamos en la ayuda en dict vemos que adopta una variedad de formas de argumentos:

    >>> help(dict)
    
    class dict(object)
     |  dict() -> new empty dictionary
     |  dict(mapping) -> new dictionary initialized from a mapping object's
     |      (key, value) pairs
     |  dict(iterable) -> new dictionary initialized as if via:
     |      d = {}
     |      for k, v in iterable:
     |          d[k] = v
     |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
     |      in the keyword argument list.  For example:  dict(one=1, two=2)

    El enfoque óptimo es la utilización de un iterable evitando la innecesaria la creación de estructuras de datos. En Python 2, código postal crea una innecesaria lista:

    >>> zip(keys, values)
    [('name', 'Monty'), ('age', 42), ('food', 'spam')]

    En Python 3, el equivalente sería:

    >>> list(zip(keys, values))
    [('name', 'Monty'), ('age', 42), ('food', 'spam')]

    y Python 3 zip simplemente crea un objeto iterable:

    >>> zip(keys, values)
    <zip object at 0x7f0e2ad029c8>

    Ya que queremos evitar la creación innecesaria de estructuras de datos, normalmente queremos evitar Python 2 zip (ya que crea un innecesarios de la lista).

    Menos performante alternativas:

    Este es un generador de expresión que se pasa a la dict constructor:

    generator_expression = ((k, v) for k, v in zip(keys, values))
    dict(generator_expression)

    o, equivalentemente:

    dict((k, v) for k, v in zip(keys, values))

    Y esta es una lista de comprensión se pasa a la dict constructor:

    dict([(k, v) for k, v in zip(keys, values)])

    En los dos primeros casos, una capa adicional de no-quirúrgico (por lo tanto innecesario) cálculo se coloca sobre la cremallera iterable, y en el caso de la comprensión de lista, una lista adicional es innecesariamente creado. Yo esperaría a todos a ser menos eficiente, y sin duda no más-así.

    De la revisión del desempeño:

    64 bits en Python 3.4.3, en Ubuntu 14.04, ordenadas de forma más rápida a la más lenta:

    >>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
    0.7836067057214677
    >>> min(timeit.repeat(lambda: dict(zip(keys, values))))
    1.0321204089559615
    >>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
    1.0714934510178864
    >>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
    1.6110592018812895
    >>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
    1.7361853648908436
    • A partir de mediados de 2019 (python 3.7.3), me parece tiempos diferentes. %%timeit devuelve 1.57 \pm 0.019 microsec para dict(zip(headList, textList)) & 1.95 \pm 0.030 microsec para {k: v for k, v in zip(headList, textList)}. Yo sugeriría que el ex de la legibilidad y de la velocidad. Obviamente, esto se presenta en el min() vs media (de) argumento para timeit.
  4. 30
    >>> keys = ('name', 'age', 'food')
    >>> values = ('Monty', 42, 'spam')
    >>> dict(zip(keys, values))
    {'food': 'spam', 'age': 42, 'name': 'Monty'}
  5. 27

    También puede utilizar el diccionario de comprensión en Python ≥ 2.7:

    >>> keys = ('name', 'age', 'food')
    >>> values = ('Monty', 42, 'spam')
    >>> {k: v for k, v in zip(keys, values)}
    {'food': 'spam', 'age': 42, 'name': 'Monty'}
  6. 14

    De una manera más natural es el uso de diccionario de comprensión

    keys = ('name', 'age', 'food')
    values = ('Monty', 42, 'spam')    
    dict = {keys[i]: values[i] for i in range(len(keys))}
    • a veces es la manera más rápida y a veces más lento para convertir a dict objeto, ¿por qué es así?, gracias tio.
  7. 10

    con Python 3.x, va por dict comprensiones de

    keys = ('name', 'age', 'food')
    values = ('Monty', 42, 'spam')
    
    dic = {k:v for k,v in zip(keys, values)}
    
    print(dic)

    Más en dict comprensiones de aquí, un ejemplo es lo que hay:

    >>> print {i : chr(65+i) for i in range(4)}
        {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
  8. 6

    Para aquellos que necesitan un código simple y no están familiarizados con zip:

    List1 = ['This', 'is', 'a', 'list']
    List2 = ['Put', 'this', 'into', 'dictionary']

    Esto puede ser hecho por una sola línea de código:

    d = {List1[n]: List2[n] for n in range(len(List1))}
    • falla en voz alta si List1 es más que List2
  9. 3
    • 2018-04-18

    La mejor solución es la que sigue:

    In [92]: keys = ('name', 'age', 'food')
    ...: values = ('Monty', 42, 'spam')
    ...: 
    
    In [93]: dt = dict(zip(keys, values))
    In [94]: dt
    Out[94]: {'age': 42, 'food': 'spam', 'name': 'Monty'}

    Tranpose es:

        lst = [('name', 'Monty'), ('age', 42), ('food', 'spam')]
        keys, values = zip(*lst)
        In [101]: keys
        Out[101]: ('name', 'age', 'food')
        In [102]: values
        Out[102]: ('Monty', 42, 'spam')
  10. 1

    puede utilizar este código a continuación:

    dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))

    Pero asegúrese de que la longitud de la lista va a ser el mismo.si la longitud no es el mismo.luego zip función turncate la más larga.

  11. 1

    Aquí es también un ejemplo de adición de un valor de la lista en que diccionario

    list1 = ["Name", "Surname", "Age"]
    list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
    dic = dict(zip(list1, list2))
    print(dic)

    siempre asegúrese de que el su «Clave»(list1) es siempre en el primer parámetro.

    {'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
  12. 1

    He tenido esta duda, mientras que yo estaba tratando de resolver un gráfico relacionadas con el problema. El problema que yo tenía era que yo necesitaba para definir un vacío de la lista de adyacencia y la quería para inicializar todos los nodos con una lista vacía, que es cuando pensé acerca de cómo puedo comprobar si es lo suficientemente rápido, me refiero a que si valdrá la pena hacer una postal de operación en lugar de la simple asignación de par clave-valor. Después de todo la mayoría de las veces, el factor tiempo es importante para romper el hielo. Por lo que realiza timeit operación para ambos enfoques.

    import timeit
    def dictionary_creation(n_nodes):
        dummy_dict = dict()
        for node in range(n_nodes):
            dummy_dict[node] = []
        return dummy_dict
    
    
    def dictionary_creation_1(n_nodes):
        keys = list(range(n_nodes))
        values = [[] for i in range(n_nodes)]
        graph = dict(zip(keys, values))
        return graph
    
    
    def wrapper(func, *args, **kwargs):
        def wrapped():
            return func(*args, **kwargs)
        return wrapped
    
    iteration = wrapper(dictionary_creation, n_nodes)
    shorthand = wrapper(dictionary_creation_1, n_nodes)
    
    for trail in range(1, 8):
        print(f'Itertion: {timeit.timeit(iteration, number=trails)}\nShorthand: {timeit.timeit(shorthand, number=trails)}')

    Para n_nodes = 10.000.000 de
    Me

    Iteración: 2.825081646999024
    De taquigrafía: 3.535717916001886

    Iteración: 5.051560923002398
    De taquigrafía: 6.255070794999483

    Iteración: 6.52859034499852
    De taquigrafía: 8.221581164998497

    Iteración: 8.683652416999394
    De taquigrafía: 12.599181543999293

    Iteración: 11.587241565001023
    De taquigrafía: 15.27298851100204

    Iteración: 14.816342867001367
    De taquigrafía: 17.162912737003353

    Iteración: 16.645022411001264
    De taquigrafía: 19.976680120998935

    Se puede ver claramente después de un cierto punto de la iteración enfoque en n_th paso le alcanza el tiempo tomado por el método abreviado en la n-1_th paso.

  13. 0

    método sin cremallera función

    l1 = [1,2,3,4,5]
    l2 = ['a','b','c','d','e']
    d1 = {}
    for l1_ in l1:
        for l2_ in l2:
            d1[l1_] = l2_
            l2.remove(l2_)
            break  
    
    print (d1)
    
    
    {1: 'd', 2: 'b', 3: 'e', 4: 'a', 5: 'c'}
    • Hola xiyurui, La entrada(l1 y l2) debe ser una lista. Si asigna la l1 y la l2 como un conjunto no puede preservar la orden de inserción. para mí, llegué a la salida como {1: ‘a’, 2: ‘c’, 3: ‘d’, 4: ‘b’, 5: ‘e’}

Dejar respuesta

Please enter your comment!
Please enter your name here