2012-06-15 7 views
18

Я пытаюсь разобрать файл с разделителями табуляции в Python, где число, размещенное на вкладках k, отличное от начала строки, должно быть помещено в k-й массив.разбор файла с разделителями табуляции в Python

Есть ли встроенная функция для этого, или лучший способ, кроме чтения строк за строкой, и выполнить всю очевидную обработку наивного решения?

+0

иногда легко забыть, но принято принимать ответ на ваш вопрос .. –

+0

@Bob не оставляйте нас висящими. – ruipacheco

ответ

3

Как это:

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

Для файла:

# 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 

Если вы хотите вход транспонированная:

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

Или (еще лучше) использовать модуль CSV в распределении по умолчанию ...

+0

В Python создание пустого списка, а затем добавление значений является анти-шаблоном. Вот о чем идет речь в списках. –

+0

@Lattyware: Я лично не считаю, что первая форма трудно читать, но вы правы - понимание вложенного списка, вероятно, более Pythonic. Ред. – dawg

+0

@drewk: '[x.split ('\ t') для f.split ('\ n')]' не имеет смысла. Нет объектов 'x' и files, у которых нет метода split(). – martineau

40

Вы можете использовать the csv module для синтаксического разбора разделенных файлов значений.

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

Где line список значений на текущей строке для каждой итерации.

Edit: Как было предложено ниже, если вы хотите читать по столбцам, а не по строкам, то лучше всего сделать, это использовать zip(): встроенная команда

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

всякий раз, когда отсутствует элемент, есть две последовательные вкладки. это будет работать? – Bob

+3

@Bob Почему бы вам не попробовать и не посмотреть? (Но да, будет). –

+3

@Lattyware: использование вами «файла» в качестве имени переменной является no-no ...;) – martineau

7

Я не думаю, что какой-либо из текущие ответы действительно делают то, что вы сказали, что хотите.

Итак, вот мое взятие:

Say эти значения, разделенные табуляцией в входном файле:

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

тогда это:

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

будет производить следующее:

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

Как вы можете видеть, он помещает k-й элемент каждой строки в k-й массив.

Смежные вопросы