2012-03-25 13 views
11

Tengo un archivo enorme (con aproximadamente 200k de entradas). Las entradas están en la forma:Crear un diccionario con una lista de listas en Python

A B C D 
B E F 
C A B D 
D 

Estoy leyendo este archivo y almacenarlo en una lista de la siguiente manera:

text = f.read().split('\n') 

Esto divide el archivo cada vez que ve una nueva línea. De ahí que el texto es como sigue:

[[A B C D] [B E F] [C A B D] [D]] 

tengo para almacenar ahora estos valores en un diccionario donde los valores clave son el primer elemento de cada lista. es decir, las claves serán A, B, C, D. Me resulta difícil introducir los valores como los elementos restantes de la lista. es decir el diccionario debe verse como:

{A: [B C D]; B: [E F]; C: [A B D]; D: []} 

he hecho lo siguiente:

inlinkDict = {} 
    for doc in text: 
    adoc= doc.split(' ') 
    docid = adoc[0] 
    inlinkDict[docid] = inlinkDict.get(docid,0) + {I do not understand what to put in here} 

Por favor, ayudar en cuanto a cómo debo añadir los valores de mi diccionario. Debería ser 0 si no hay elementos en la lista, excepto el que será el valor clave. Al igual que en el ejemplo de 0.

+0

¿Quiere el diccionario estar '{A: [B, C, D]; B: [E, F]; C: [A, B, D]; D: []} '? O tal vez '{A:" B C D "; B: "E F"; C: "A B D"; D: 0} '? – huon

+0

Por favor edite su pregunta para decir lo que quiere hacer con las llaves duplicadas; Por ejemplo, ¿qué pasa si tienes una 5ª línea que contiene 'A P Q R'? ¿Cómo desea almacenar los valores B C D ... como una lista '['B', 'C', 'D']'?Si es mucho mejor representar el caso de una lista vacía como una lista vacía '[]', no como un número entero '0'. –

+0

@JohnMachin: no hay valores duplicados. Y sí, almacenar valores como una lista definitivamente ayudará. Editaré mi pregunta. – Nerd

Respuesta

17

Trate de usar una rebanada:

inlinkDict[docid] = adoc[1:] 

Esto le dará una lista vacía en lugar de un 0 para el caso en el que sólo el valor de la clave está en la línea. Para conseguir un 0 en vez usted podría utilizar la asignación condicional: forma

inlinkDict[docid] = adoc[1:] if adoc[1:] else 0 

más fácil con una comprensión dict:

>>> with open('/tmp/spam.txt') as f: 
... data = [line.strip().split() for line in f.readlines()] 
... 
>>> {d[0]: d[1:] for d in data} 
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []} 
>>> {d[0]: ' '.join(d[1:]) if d[1:] else 0 for d in data} 
{'A': 'B C D', 'C': 'A B D', 'B': 'E F', 'D': 0} 

Nota: las claves de diccionario deben ser únicos, por lo que si usted tiene, por ejemplo, dos líneas que comienzan con 'C' la primera será escrita en exceso.

+0

esto funcionará onli en 2.7 python la mejor manera es dict ([(d [0], d [1:]) para d en datos]) – pod2metra

+0

Esto también leerá todo el archivo en la memoria. –

18

Un diccionario por comprensión reduce el trabajo de esta tarea:

>>> s = [['A','B','C','D'], ['B','E','F'], ['C','A','B','D'], ['D']] 
>>> {t[0]:t[1:] for t in s} 
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []} 
+1

Si está usando una versión anterior de python que no tiene comprensión de dicto, puede usar 'dict (t [0], t [1:] para t en s)' en su lugar – forivall

+11

Y si está usando una versión de python que es anterior a las expresiones del generador, puede usar '' dict ([(t [0], t [1:]) para t en s]) ''. Y, si está usando una versión anterior, puede usar '' para t en s: d [t [0]] = t [1:] ''. Y, si está tan atrás en el tiempo que Python no existe, puede usar Dartmouth BASIC para DIM una matriz para que pueda simular una tabla hash escribiendo su propia función hash. Y, si está trabajando en un sistema sin un lenguaje de nivel superior, puede traducir a mano su código de ensamblador al lenguaje de la máquina e ingresar su programa con los interruptores de palanca ... –

+0

Ha, ha, ha. Es solo que 2.5 y 2.6 siguen siendo muy comunes, y las definiciones dict solo se agregaron en 2.7. – forivall

4

La respuesta aceptada es correcta, excepto que lee el archivo en la memoria (puede no ser conveniente si usted tiene un archivo de gran tamaño), y sobrescribirá claves duplicadas.

Un enfoque alternativo utilizando defaultdict, que está disponible a partir de Python 2.4 resuelve este:

from collections import defaultdict 
d = defaultdict(list) 
with open('/tmp/spam.txt') as f: 
    for line in f: 
    parts = line.strip().split() 
    d[parts[0]] += parts[1:] 

de entrada:

 
A B C D 
B E F 
C A B D 
D 
C H I J 

Resultado:

>>> d = defaultdict(list) 
>>> with open('/tmp/spam.txt') as f: 
... for line in f: 
...  parts = line.strip().split() 
...  d[parts[0]] += parts[1:] 
... 
>>> d['C'] 
['A', 'B', 'D', 'H', 'I', 'J'] 
Cuestiones relacionadas