Избегая вложенности двух петель - PullRequest
2 голосов
/ 02 марта 2010

Пожалуйста, посмотрите на код ниже:

import string
from collections import defaultdict



first_complex=open( "residue_a_chain_a_b_backup.txt", "r" )
first_complex_lines=first_complex.readlines()
first_complex_lines=map( string.strip, first_complex_lines )
first_complex.close()

second_complex=open( "residue_a_chain_a_c_backup.txt", "r" )
second_complex_lines=second_complex.readlines()
second_complex_lines=map( string.strip, second_complex_lines )
second_complex.close()
list_1=[]
list_2=[]
for x in first_complex_lines:
    if x[0]!="d":
        list_1.append( x )
for y in second_complex_lines:
    if y[0]!="d":
        list_2.append( y ) 
j=0
list_3=[]      
list_4=[]
for a in list_1:
    pass
    for b in list_2:
        pass
        if a==b:
            list_3.append( a )    

kvmap=defaultdict( int )
for k in list_3:
    kvmap[k]+=1 
print kvmap

Обычно я использую izip или izip_longest, чтобы объединить два цикла, но на этот раз длина файлов отличается. Я не хочу ни одной записи. Если я использую описанный выше метод, время выполнения становится добавочным и бесполезным. Как мне заставить эти два цикла работать?

Cheers, Chavanak

Ответы [ 4 ]

8 голосов
/ 02 марта 2010

Вы хотите преобразовать list_2 в набор и проверить членство:

list_1 = ['a', 'big', 'list']
list_2 = ['another', 'big', 'list']

target_set = set(list_2)

for a in list_1:
    if a in target_set:
         print a

Выходы:

big
list

Набор дает вам преимущество времени доступа O (1) для определения членства, так что вам нужно только один раз полностью прочитать list_2 (при создании набора). После этого каждое сравнение происходит в постоянное время.

3 голосов
/ 02 марта 2010

Следующий код выполняет те же задачи, что и ваш, с большей краткостью, прямотой и скоростью:

with open('residue_a_chain_a_b_backup.txt', 'r') as f:
  list1 = [line for line in f if line[0] != 'd']
with open('residue_a_chain_a_c_backup.txt', 'r') as f:
  list2 = [line for line in f if line[0] != 'd']
set2 = set(list2)
list3 = [line for line in list1 if line in set2]

следующая гистограмма lint3 в kvmap уже подходит для вашего кода. (В Python 2.5 для использования оператора with необходимо запустить модуль с from __future__ import with_statement; в 2.6 нет необходимости в этом «импорте из будущего», хотя это не повредит, если вы хотите оставить его в ).

2 голосов
/ 15 апреля 2010

Это пересечение двух наборов, которое вы хотите, если вы можете использовать операцию взаимодействия с наборами:

list_1 = ['a', 'big', 'list']
list_2 = ['another', 'big', 'list']

intersection = (set(list_1) & set(list_2))

После запуска interaction представляет собой set, содержащий общие элементы list_1 и list_2.

1 голос
/ 02 марта 2010

Совершенствование кода Алекса:

with open('residue_a_chain_a_c_backup.txt', 'r') as f:
  set2 = set([line.strip() for line in f if line[0] != 'd'])

with open('residue_a_chain_a_b_backup.txt', 'r') as f:
  list1 = [line.strip() for line in f if line.strip() in set2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...