避免嵌套两个for循环

时间:2010-03-02 15:42:41

标签: python for-loop

请查看以下代码:

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来为两个循环播放,但这次文件的长度是不同的。我不想要一个无条目。如果我使用上述方法,则运行时间变为增量且无用。我怎么能让两个for循环运行?

干杯, Chavanak

4 个答案:

答案 0 :(得分:8)

您想将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一次(创建集合时)。此后,每次比较都在不断的时间内进行。

答案 1 :(得分:3)

以下代码以更简洁,直接和更快的速度执行与您相同的任务:

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 :(得分:2)

它是你想要的两个集合的交集,如果是这样你可以使用set interaction操作:

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

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

运行此操作后,interactionset,其中包含list_1list_2的常见项。

答案 3 :(得分:1)

非常轻微地改进Alex的代码:

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]