python - tuplas - Lista anidada a dic
llenar una lista en python (4)
Intento crear dict
por list
anidada:
groups = [[''Group1'', ''A'', ''B''], [''Group2'', ''C'', ''D'']]
L = [{y:x[0] for y in x if y != x[0]} for x in groups]
d = { k: v for d in L for k, v in d.items()}
print (d)
{''B'': ''Group1'', ''C'': ''Group2'', ''D'': ''Group2'', ''A'': ''Group1''}
Pero parece un poco complicado.
¿Hay una solución mejor?
Creo que una solución de línea es un poco de confusión. Yo escribiría el código como abajo
groups = [[''Group1'', ''A'', ''B''], [''Group2'', ''C'', ''D'']]
result = {}
for group in groups:
for item in group[1:]:
result[item] = group[0]
print result
Esta es esencialmente una versión más bonita de Willem:
>>> groups = [[''Group1'', ''A'', ''B''], [''Group2'', ''C'', ''D'']]
>>> {k:g for g,*tail in groups for k in tail}
{''B'': ''Group1'', ''A'': ''Group1'', ''C'': ''Group2'', ''D'': ''Group2''}
Pero no funcionará con una lista vacía: groups = [[],[''A'',''B'']]
>>> {k:head for head, *tail in grps for k in tail}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <dictcomp>
ValueError: not enough values to unpack (expected at least 1, got 0)
Qué pasa:
d = {k:row[0] for row in groups for k in row[1:]}
Esto da:
>>> {k:row[0] for row in groups for k in row[1:]}
{''D'': ''Group2'', ''B'': ''Group1'', ''C'': ''Group2'', ''A'': ''Group1''}
Así que iteras sobre cada row
en los groups
. El primer elemento de la fila se toma como valor ( row[0]
) y se itera sobre la row[1:]
para obtener todas las claves k
.
Por extraño que parezca, esta expresión también funciona cuando le das una fila vacía (como groups = [[],[''A'',''B'']]
). Esto se debe a que la row[1:]
estará vacía y, por lo tanto, la parte de la row[0]
nunca se evaluará:
>>> groups = [[],[''A'',''B'']]
>>> {k:row[0] for row in groups for k in row[1:]}
{''B'': ''A''}
También me gusta la solución de Willem, pero solo para completar ...
otra variación que usa itertools y una función generadora (solo Python 3.x)
def pairs(groups):
for value,*keys in groups:
for key_value in zip(keys, itertools.repeat(value)):
yield key_value
dict(pairs(groups))
{''A'': ''Group1'', ''B'': ''Group1'', ''C'': ''Group2'', ''D'': ''Group2''}