2012-06-15 396 views
18

Estoy tratando de analizar un archivo separado por tabuladores en Python donde un número colocado k pestañas separadas desde el comienzo de una fila, debe colocarse en la matriz k-th.analizando un archivo separado por tabuladores en Python

¿Hay una función incorporada para hacer esto, o una manera mejor, que no sea leer línea por línea y hacer todo el procesamiento obvio que una solución ingenua podría realizar?

+0

a veces fácil de olvidar, pero es costumbre aceptar una respuesta a su pregunta .. –

+0

@Bob no nos deje colgando. – ruipacheco

Respuesta

3

De esta manera:

>>> s='1\t2\t3\t4\t5' 
>>> [x for x in s.split('\t')] 
['1', '2', '3', '4', '5'] 

Para un archivo:

# create test file: 
>>> with open('tabs.txt','w') as o: 
... s='\n'.join(['\t'.join(map(str,range(i,i+10))) for i in [0,10,20,30]]) 
... print >>o, s 

#read that file: 
>>> with open('tabs.txt','r') as f: 
... LoL=[x.strip().split('\t') for x in f] 
... 
>>> LoL 
[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], 
['10', '11', '12', '13', '14', '15', '16', '17', '18', '19'], 
['20', '21', '22', '23', '24', '25', '26', '27', '28', '29'], 
['30', '31', '32', '33', '34', '35', '36', '37', '38', '39']] 
>>> LoL[2][3] 
23 

Si desea que la entrada de la transposición:

>>> with open('tabs.txt','r') as f: 
... LoT=zip(*(line.strip().split('\t') for line in f)) 
... 
>>> LoT[2][3] 
'32' 

O (mejor aún) utilizar el módulo csv en la distribución predeterminada ...

+0

En Python, hacer una lista vacía y luego agregar valores es un antipatrón. Para eso están las listas de comprensión. –

+0

@Lattyware: personalmente no encuentro la primera forma difícil de leer, pero tiene razón: una lista anidada es probablemente más pitonica. Editado – dawg

+0

@drewk: '[x.split ('\ t') para f.split ('\ n')]' no tiene sentido. No hay 'x' y los objetos de los archivos no tienen un método' split() '. – martineau

40

Puede usar the csv module para analizar fácilmente los archivos de valores separados por tabulaciones.

import csv 

with open("tab-separated-values") as tsv: 
    for line in csv.reader(tsv, dialect="excel-tab"): #You can also use delimiter="\t" rather than giving a dialect. 
     ... 

Dónde line es una lista de los valores de la fila actual para cada iteración.

Edit: Como se sugiere a continuación, si desea leer por la columna, y no por fila, a continuación, lo mejor que puede hacer es usar la orden interna zip():

with open("tab-separated-values") as tsv: 
    for column in zip(*[line for line in csv.reader(tsv, dialect="excel-tab")]): 
     ... 
+0

cada vez que falta un elemento, hay dos pestañas consecutivas. ¿Eso funcionará? – Bob

+3

@Bob ¿Por qué no lo intentas y ves? (Pero sí, lo hará). –

+3

@Lattyware: el uso de "archivo" como nombre de variable es un no-no ...;) – martineau

7

no creo que ninguna de las las respuestas actuales realmente hacen lo que dijiste que querías.

lo tanto, aquí está mi opinión:

dicen que estos son los valores separados por tabuladores en el archivo de entrada:

1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
16 17 18 19 20 

entonces esto:

with open("tab-separated-values.txt") as input: 
    print zip(*(line.strip().split('\t') for line in input)) 

produciría lo siguiente:

[('1', '6', '11', '16'), 
('2', '7', '12', '17'), 
('3', '8', '13', '18'), 
('4', '9', '14', '19'), 
('5', '10', '15', '20')] 

Como puede ver, coloca el elemento k-ésimo de cada fila en la matriz k-ésima.

Cuestiones relacionadas