разбор файла, разделенного табуляцией, в Python

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

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


person Bob    schedule 15.06.2012    source источник
comment
иногда легко забыть, но принято принимать ответ на свой вопрос..   -  person Scott Prive    schedule 21.06.2017
comment
@Боб, не оставляй нас в покое.   -  person ruipacheco    schedule 18.10.2017


Ответы (3)


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

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 — это список значений в текущей строке для каждой итерации.

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

with open("tab-separated-values") as tsv:
    for column in zip(*[line for line in csv.reader(tsv, dialect="excel-tab")]):
        ...
person Gareth Latty    schedule 15.06.2012
comment
всякий раз, когда элемент отсутствует, есть две последовательные вкладки. это сработает? - person Bob; 16.06.2012
comment
@Bob Почему бы тебе не попробовать и не посмотреть? (Но да, будет). - person Gareth Latty; 16.06.2012
comment
@Lattyware: использование вами файла в качестве имени переменной - нет-нет ... ;) - person martineau; 16.06.2012
comment
@martineau: из всех встроенных имен по умолчанию для повторной привязки file является наименее проблематичным, особенно. потому что его даже не существует в 3. У вас может быть файл в файлах:` когда вы вырвете его из моих холодных, мертвых рук! ;^) - person DSM; 16.06.2012
comment
@martineau Я человек Python 3.x, поэтому я иногда забываю, что это разбивает file в 2.x. Хорошая мысль, однако. Отредактировано. - person Gareth Latty; 16.06.2012

Я не думаю, что какой-либо из текущих ответов действительно делает то, что вы сказали, что хотите. (Исправление: теперь я вижу, что @Gareth Latty / @Lattyware включил мой ответ в свой собственный как «Редактировать» ближе к концу.)

Во всяком случае, вот мое мнение:

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

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 inp:
    print( list(zip(*(line.strip().split('\t') for line in inp))) )

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

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

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

person martineau    schedule 16.06.2012

Нравится:

>>> 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 в дистрибутиве по умолчанию...

person dawg    schedule 15.06.2012
comment
В Python создание пустого списка, а затем добавление значений — это антишаблон. Вот для чего нужны списки. - person Gareth Latty; 16.06.2012
comment
@Lattyware: лично я не нахожу первую форму сложной для чтения, но вы правы - понимание вложенного списка, вероятно, более похоже на Python. Отредактировано. - person dawg; 16.06.2012
comment
@drewk: [x.split('\t') for f.split('\n')] не имеет смысла. Нет x, а объекты файлов не имеют метода split(). - person martineau; 16.06.2012
comment
@martineau: прекрасный пример того, зачем использовать модуль csv, не так ли? опечатка исправлена. я проверил это - person dawg; 16.06.2012
comment
@drewk: Ну, не так уж много ... скорее всего, последнее, ИМХО. ;) - person martineau; 16.06.2012
comment
@martineau: Интересно, что вы интерпретировали, что OP хотел перенести строку / столбец читаемого файла. Непонятно мне так или иначе. Если это то, что нужно, используйте zip(), как вы это делали. Спасибо за ваш терпеливый коучинг... - person dawg; 16.06.2012