У меня есть текстовый файл с разделителями табуляции и выглядит так:

1_0 NP_045689 100,00 279 0 0 18 296 18 296 3e-156 539

1_0 NP_045688 54,83 259 108 6 45 296 17 273 2e-61 224

Мне нужно разобрать конкретные столбцы, такие как столбец 2.

Я пробовал с кодом ниже:

z = open('output.blast', 'r')
for line in z.readlines():
    for col in line:
        print col[1]
z.close()

Но я получаю индекс вне диапазона ошибок.

2
Craig David 1 Июл 2010 в 21:21

5 ответов

Лучший ответ

Ознакомьтесь с модулем csv. Это должно помочь вам, если вы планируете делать больше с файлами, разделенными табуляцией. Приятно, что вы можете присваивать имена различным столбцам.

5
JAB 1 Июл 2010 в 17:24

Вот почему ваш код работает неправильно:

for col in line:

Будет перебирать каждый символ в строке.

    print col[1]

Символ - это строка длиной 1, поэтому col [1] всегда будет давать индекс из-за ошибки диапазона.

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

Я также рекомендую избегать использования readlines - он будет считывать весь файл в память, что может вызвать проблемы, если он очень большой. Вместо этого вы можете перебирать открытый файл по очереди:

z = open('output.blast', 'r')
for line in z:
    ...
0
Dave Kirby 1 Июл 2010 в 18:18
z = open('output.blast', 'r')
for line in z.readlines():
    cols = line.split('\t'):
        print cols[1]
z.close()

Сначала необходимо split() строка на символах табуляции.

В качестве альтернативы вы можете использовать модуль Python csv в режиме табуляции.

7
Amber 1 Июл 2010 в 18:11

На этот вопрос уже был дан ответ, но я подумала, что поделюсь использованием именованных кортежей для такого рода ситуаций, поскольку это обеспечивает приятный доступ к атрибуту типа object.attribute.

from collections import namedtuple
import csv
rec = namedtuple('rec', 'col1, col2, col3, col4, col5')
for r in map(rec._make, csv.reader(open("myfile.tab", "rb"), delimiter='\t')):
    print r.col2, r.col5

Дополнительную информацию смотрите в документации по коллекциям Python.

2
rorycl 14 Апр 2012 в 09:38
import csv,StringIO
text="""1_0 NP_045689   100.00  279 0   0   18  296 18  296 3e-156  539
1_0 NP_045688   54.83   259 108 6   45  296 17  273 2e-61   224"""

f = csv.reader(StringIO.StringIO(text), delimiter='\t')
for row in f:
    print row[1]

Две вещи на заметку:

Аргумент delimiter для метода reader сообщает модулю csv, как разбивать текстовую строку. Проверьте другие аргументы функции reader для расширения функциональности (например: quotechar)

Я использую StringIO, чтобы обернуть текстовый пример как объект файла, вам это не нужно, если вы используете ссылку на файл.

Пример:

f=csv.reader(open('./test.csv'),delimiter='\t')
3
Amber 1 Июл 2010 в 18:12