避免嵌套两个for循环

2 投票
4 回答
1727 浏览
提问于 2025-04-15 19:55

请看下面的代码:

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 循环结合在一起,但这次文件的长度不一样。我不想要出现 None 的情况。如果我用上面的方法,运行时间会变得很慢,没什么用。我该怎么让这两个 for 循环一起运行呢?

谢谢,

Chavanak

4 个回答

2

你想要的是两个集合的交集吗?如果是的话,你可以使用集合的交集操作:

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

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

运行这个之后,interaction 就是一个 set,里面包含了 list_1list_2 中的共同元素。

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中就不需要这个“从未来导入”的语句了,不过如果你想保留它也没问题。)

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(在创建集合的时候)。之后,每次检查元素是否在集合里都非常快。

撰写回答