Как мне заставить мой внутренний цикл for повторяться каждый раз, когда повторяется мой внешний цикл for?

#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(): будет работать только на первой итерации внешнего цикла)