#python
#python
Вопрос:
У меня есть два файла, и я пытаюсь добавить строки из последнего столбца второго файла в массив внутри массива, содержащего информацию в первом файле. Я хочу, чтобы эти строки добавлялись, только если числа во втором столбце второго файла находятся между номерами первого и второго столбцов первого файла.
Вот мои файлы:
reads.bed:
chromA 10 69 read1
chromA 10 35 read2
chromA 10 55 read3
chromA 15 69 read4
chromA 80 119 read5
chromA 80 111 read6
chromA 90 119 read7
chromA 101 119 read8
feats.bed:
chromA 10 19 feat1
chromA 30 39 feat2
chromA 50 69 feat3
chromA 80 89 feat4
chromA 100 119 feat5
Вот мой код:
feat_bed=open("feats.bed","r")
read_bed=open("reads.bed","r")
read_coords=[]
for line in read_bed.readlines():
line=line.strip()
line=line.split("t")
read_coords.append([int(line[1]),int(line[2]),str(line[3]),[]])
for read in read_coords:
for feat in feat_bed.readlines():
feat=feat.strip()
feat=feat.split("t")
if int(read[1]) > int(feat[1]) >= int(read[0]):
read[3].append(str(feat[3]))
print read
Мой ожидаемый результат будет:
[10, 69, 'read1', ['feat1', 'feat2', 'feat3']]
[10, 35, 'read2', ['feat1', 'feat2']]
[10, 55, 'read3', ['feat1', 'feat2', 'feat3']]
[15, 69, 'read4', ['feat2', 'feat3']]
[80, 119, 'read5', ['feat4', 'feat5']]
[80, 111, 'read6', ['feat4', 'feat5']]
[90, 119, 'read7', ['feat5']]
[101, 119, 'read8', []]
Вместо этого мой внутренний цикл for, похоже, повторяется только в первый раз, а затем останавливается, поэтому мой фактический результат:
[10, 69, 'read1', ['feat1', 'feat2', 'feat3']]
[10, 35, 'read2', []]
[10, 55, 'read3', []]
[15, 69, 'read4', []]
[80, 119, 'read5', []]
[80, 111, 'read6', []]
[90, 119, 'read7', []]
[101, 119, 'read8', []]
Я не понимаю, почему мой внутренний цикл прекращает повторение после первой итерации моего внешнего цикла. Если бы кто-нибудь мог указать, что я делаю неправильно, это было бы очень полезно. Спасибо.
Ответ №1:
Это происходит потому, что readlines()
считывает все строки с текущей позиции в файле. Итак, после первого вызова readlines
указатель на файл находится в конце файла, и все последующие вызовы readlines()
будут возвращать пустой список.
Вы хотите заранее сохранить строки в список, например feat_lines = feat_bed.readlines()
, а затем выполнить итерацию по этому предварительно сохраненному списку строк, например: for feat in feat_lines:
.
Комментарии:
1. Отличный совет Мерику! Ваше предложение сработало, и теперь я лучше понимаю механику readlines().
2. Отлично! Рад слышать. Помните, что все файловые методы работают одинаково (
read()
,readline()
и т.д.). Есть возможность использоватьseek
для перемещения указателя файла обратно в начало, но я предпочитаю избегать этого
Ответ №2:
Использование внутренних циклов с идентификатором:
feat_bed=open("feats.bed","r")
read_bed=open("reads.bed","r")
read_coords=[]
for line in read_bed.readlines():
line=line.strip()
line=line.split("t")
read = [int(line[1]),int(line[2]),str(line[3]),[]]
for feat in feat_bed.readlines():
feat=feat.strip()
feat=feat.split("t")
if int(read[1]) > int(feat[1]) >= int(read[0]):
read[3].append(str(feat[3]))
print read
Комментарии:
1. У этого все еще та же проблема (
for feat in feat_bed.readlines():
будет работать только на первой итерации внешнего цикла)