2010-07-21 7 views
8

tengo una lista de cadenas analizadas desde algún lugar, en el siguiente formato:¿Manera pitónica de convertir una lista de cadenas en un diccionario con las cadenas de índice impar como claves e incluso las indexadas como valores?

[key1, value1, key2, value2, key3, value3, ...] 

Me gustaría crear un diccionario basado en esta lista, así:

{key1:value1, key2:value2, key3:value3, ...} 

Un ordinaria for el bucle con compensaciones de índice probablemente sería el truco, pero me pregunto si hay una manera Pythonic de hacer esto. Las comprensiones de listas parecen interesantes, pero parece que no puedo encontrar la forma de aplicarlas a este problema en particular.

¿Alguna idea?

Respuesta

13

Usted puede tratar de:

dict(zip(l[::2], l[1::2])) 

Explicación: nos dividido la lista en dos listas, una de la pareja y uno de los elementos impares, llevándolos en pasos de dos a partir de la primera o la segundo elemento (que es el l[::2] y l[1::2]). Luego usamos el zip incorporado a las dos listas en una lista de pares. Finalmente, llamamos al dict para crear un diccionario a partir de estos pares clave-valor.

Esto es ~4n en el tiempo y ~4n en el espacio, incluido el diccionario final. Es probable que sea más rápido que un bucle, sin embargo, ya que el zip, dict, y los operadores de rebanado están escritos en C

+0

Exactamente lo que necesitaba y muy bien explicado, gracias pavpanchekha mucho! – KennyDeriemaeker

0
result = dict(grouper(2, L)) 

grouper es una función que forma pares en una lista, que se le da en el itertools receipes:

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

dict toma una lista de (key,value) pares y hace una dict de ellos.

También podría escribir result = dict(zip(*[iter(L)]*2)) y confundir a la mayoría de los lectores :-)

+0

'result = dict (zip (* [iter (L)] * 2))' no se garantiza que funcione (zip no garantiza el orden de evaluación de sus argumentos). Debería usar 'result = dict (izip (* [iter (L)] * 2))' en lugar de ser un modelo de claridad (!) Que garantiza el orden correcto de evaluación. – Duncan

+1

@Ducan: ¿De dónde sacaste esa idea (equivocada)? Ver http://docs.python.org/library/functions.html#zip 'izip' es solo la versión de iterador de' zip'. –

3
In [71]: alist=['key1', 'value1', 'key2', 'value2', 'key3', 'value3'] 

In [72]: dict(alist[i:i+2] for i in range(0,len(alist),2)) 
Out[72]: {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} 
1

Además de solución a corto y perfectamente bien de pavpanchekha, se puede utilizar una expresión generadora (una lista por comprensión es sólo una expresión generadora alimentan a constructor de la lista - en realidad es más potente und universal), para la bondad adicional:

dict((l[i], l[l+1]) for i in range(0, len(l)-1, 2)) 

Aparte de ser muy fresco y funcional, es también un mejor algoritmo: a menos que la aplicación de la dict es especiall y estúpido (es poco probable que se considere una función incorporada), esto consumirá la misma cantidad de memoria para cada tamaño de l (es decir, se ejecuta en constante aka O (1) espacio) ya que procesa un par a la vez en lugar de crear una lista completamente nueva de tuplas primero.

5

una buena oportunidad para mostrar mi idioma pitón favorita:

>>> S = [1,2,3,4,5,6] 
>>> dict(zip(*[iter(S)]*2)) 
{1: 2, 3: 4, 5: 6} 

Esa línea complicado pasa dos argumentos a zip() donde cada argumento es el mismo iterador sobre S. zip() crea tuplas 2-ítem, tirando de el iterador sobre zip cada vez. dict() luego convierte esas tuplas a un diccionario.

extrapolar:

S = [1,2,3,4,5,6] 

I = iter(S) 
dict(zip(I,I)) 
+1

Eso es IMPRESIONANTE. Puntos principales de brownie! – katrielalex

Cuestiones relacionadas