python list dictionary

python - ¿Cómo crear un diccionario usando una sola lista?



dictionary (5)

La biblioteca more-itertools contiene una función split_before() que es muy útil para este propósito:

{s[0]: tuple(s[1:]) for s in mt.split_before(x, lambda e: e.startswith(''URL''))}

Creo que esto es más limpio que cualquiera de los otros enfoques en las respuestas publicadas antes de este, pero introduce una dependencia externa (a menos que vuelva a implementar la función), lo que hace que no sea apropiado para cada situación.

Si su caso de uso real incluye URL reales o algo más, en lugar de cadenas del formulario URL# , simplemente reemplace lambda e: e.startswith(''URL'') con cualquier función que pueda usar para seleccionar los elementos clave aparte del valor elementos.

Tengo una lista de url y encabezados de un sitio de periódicos en mi país. Como ejemplo general:

x = [''URL1'',''news1'',''news2'',''news3'',''URL2'',''news1'',''news2'',''URL3'',''news1'']

Cada elemento de URL tiene una secuencia correspondiente de elementos de ''noticias'', que pueden diferir en longitud. En el ejemplo anterior, URL1 tiene 3 noticias correspondientes y URL3 tiene solo una.

A veces, una URL no tiene el elemento correspondiente "noticias":

y = [''URL4'',''news1'',''news2'',''URL5'',''URL6'',''news1'']

Puedo encontrar fácilmente cada índice de URL y los elementos de "noticias" de cada URL.

Mi pregunta es: ¿es posible transformar esta lista en un diccionario en el que el elemento URL es la clave y los elementos "noticias" son un valor de lista / tupla?

Rendimiento esperado

z = {''URL1'':(''news1'', ''news2'', ''news3''), ''URL2'':(''news1'', ''news2''), ''URL3'':(''news1''), ''URL4'':(''news1'', ''news2''), ''URL5'':(), ''URL6'':(''news1'')}

He visto una pregunta similar en esta post , pero no resuelve mi problema.


Otra solución usando groupby , one-liner:

x = [''URL1'',''news1'',''news2'',''news3'',''URL2'',''news1'',''news2'',''URL3'',''news1'', ''URL4'',''news1'',''news2'',''URL5'',''URL6'',''news1''] from itertools import groupby out = {k: tuple(v) for _, (k, *v) in groupby(x, lambda k, d={''g'':0}: (d.update(g=d[''g'']+1), d[''g'']) if k.startswith(''URL'') else (None, d[''g'']))} from pprint import pprint pprint(out)

Huellas dactilares:

{''URL1'': (''news1'', ''news2'', ''news3''), ''URL2'': (''news1'', ''news2''), ''URL3'': (''news1'',), ''URL4'': (''news1'', ''news2''), ''URL5'': (), ''URL6'': (''news1'',)}


Puede usar itertools.groupby con una función key para identificar una URL:

from itertools import groupby def _key(url): return url.startswith("URL") #in the body of _key, write code to identify a URL data = [''URL1'',''news1'',''news2'',''news3'',''URL2'',''news1'',''news2'',''URL3'',''news1'', ''URL4'',''news1'',''news2'',''URL5'',''URL6'',''news1''] new_d = [list(b) for _, b in groupby(data, key=_key)] grouped = [[new_d[i], tuple(new_d[i+1])] for i in range(0, len(new_d), 2)] result = dict([i for [*c, a], b in grouped for i in [(i, ()) for i in c]+[(a, b)]])

Salida:

{ ''URL1'': (''news1'', ''news2'', ''news3''), ''URL2'': (''news1'', ''news2''), ''URL3'': (''news1'',), ''URL4'': (''news1'', ''news2''), ''URL5'': (), ''URL6'': (''news1'',) }


Puedes hacerlo así:

>>> y = [''URL4'',''news1'',''news2'',''URL5'',''URL6'',''news1''] >>> result = {} >>> current_url = None >>> for entry in y: ... if entry.startswith(''URL''): ... current_url = entry ... result[current_url] = () ... else: ... result[current_url] += (entry, ) ... >>> result {''URL4'': (''news1'', ''news2''), ''URL5'': (), ''URL6'': (''news1'',)}


Simplemente puede usar los índices de las claves de URL en la lista y tomar lo que hay entre los índices y asignarlos al primer

Me gusta esto:

x = [''URL1'',''news1'',''news2'',''news3'',''URL2'',''news1'',''news2'',''URL3'',''news1''] urls = [x.index(y) for y in x if ''URL'' in y] adict = {} for i in range(0, len(urls)): if i == len(urls)-1: adict[x[urls[i]]] = x[urls[i]+1:len(x)] else: adict[x[urls[i]]] = x[urls[i]+1:urls[i+1]] print(adict)

salida:

{''URL1'': [''news1'', ''news2'', ''news3''], ''URL2'': [''news1'', ''news2''], ''URL3'': [''news1'']}