2010-03-02 213 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