2012-06-15 8 views
18

Ich versuche, eine lasche separierte Datei in Python, wo eine Reihe platziert k tabs abgesehen vom Anfang einer Zeile zu analysieren, sollte in den k-te-Array platziert werden.Parsen eine lasche separierte Datei in Python

Gibt es eine eingebaute Funktion, dies zu tun, oder eine bessere Art und Weise, die nicht Zeile für Zeile zu lesen und alle die offensichtliche Verarbeitung einer naive Lösung würde durchführen tun?

+0

manchmal einfach zu vergessen, aber es ist üblich, eine Antwort auf Ihre Frage zu übernehmen .. –

+0

@Bob lassen Sie uns nicht hängen. – ruipacheco

Antwort

3

So:

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

Für eine Datei:

# 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 

Wenn Sie die Eingabe umgesetzt:

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

Oder (besser noch) das csv-Modul verwenden in der Standardverteilung ...

+0

In Python ist das Erstellen einer leeren Liste und das Anhängen von Werten ein Anti-Pattern. Dafür gibt es Listenkompressen. –

+0

@Lattyware: Ich persönlich finde nicht die erste Form schwer zu lesen, aber Sie haben Recht - eine verschachtelte Liste Verständnis ist wahrscheinlich Pythonic. Bearbeitet. – dawg

+0

@drewk: '[x.split ('\ t') für f.split ('\ n')]' macht keinen Sinn. Es gibt kein 'x' und Dateiobjekte haben keine' split() 'Methode. – martineau

40

Sie können the csv module verwenden Tab getrennt Wert Dateien leicht zu analysieren.

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. 
     ... 

Wo line für jede Iteration eine Liste der Werte für die aktuelle Zeile ist.

Edit: Wie weiter unten vorgeschlagen, wenn Sie mit dem Spalte lesen möchten, und nicht für Zeile, dann ist das Beste, was zu tun, um die zip() builtin verwenden:

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

Wenn ein Element fehlt, gibt es zwei aufeinanderfolgende Registerkarten. wird es funktionieren? – Bob

+3

@Bob Warum versuchst du es nicht und siehst? (Aber ja, wird es). –

+3

@Lattyware: Ihre Verwendung von "Datei" als Variablenname ist ein No-No ...;) – martineau

7

Ich glaube nicht eine der Aktuelle Antworten tun wirklich, was Sie sagten, dass Sie wollen.

So, hier ist mein nehmen:

sagen, dass diese die Registerkarte getrennte Werte in der Eingabedatei sind:

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

dann das:

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

folgendes erzeugt:

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

Wie Sie sehen können, wird das k-te Element jeder Zeile in das k-te Array eingefügt.