2010-03-02 164 views
2

请看看下面的代码:避免嵌套两个for循环

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

+6

顺便问一下,你的代码是完全无关的cruft。您的文件名对我们毫无意义,并且使您的代码无法运行。另外,j从不使用。此外,kvmap的东西是无关紧要的。如果你修剪不必要的细节,人们会更容易看到你在问什么。您通常会更容易看到您的代码真正发生了什么。 – jcdyer 2010-03-02 15:49:30

+0

单词放入list_3的顺序是否重要?此外,是否存在或可能会在list_1或list_2中重复出现的单词? – 2010-03-02 16:04:28

回答

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 

一套给你,啊的优势(1)确定成员身份的访问时间,因此您只需要一次性阅读list_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,没有必要,“从今后进口”,虽然它没有任何伤害,如果你希望把它留在)。

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] 
+0

再细化一下,如果你使用的是上下文处理器,你显然是python> 2.4,这意味着你可以在你的set函数中使用一个生成器表达式,并保存自己的列表创建:'set2 = set(line如果line [0]!='d')'。 – jcdyer 2010-03-02 18:51:50

+0

出于某种原因,我说出了自己,但我现在不能明白为什么。你需要第二组括号吗?我很想知道关于发电机的理解。 – 2010-03-02 23:32:39

2

难道你希望两个集合的交集,如果是的话,你可以使用set交互操作:

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

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

运行此之后,interaction是一个set包含共同项目list_1list_2