2010-07-19 121 views
0

我是編程新手,在計算嵌套循環時遇到了一些問題。我有一個我想從大文件中提取的數據列表。我能夠從較大的文件中成功提取一項數據,但是我需要從這個數千個試驗的較大文件中提取100個不同的試驗。每個試驗都是較大文件的一行數據。這是我用來一次一個地成功提取一行數據的程序。在這個例子中,它提取了試驗1的數據。它基於我在之前的問題和教程中看到的例子。問題是我不需要試用1-100或任何有序的模式。我需要試用134,274,388等。它跳過。所以我不知道如何使用for語句做一個嵌套循環,如果它沒有我可以輸入的範圍。任何幫助表示讚賞。謝謝。關於嵌套循環的問題

completedataset = open('completedataset.txt', 'r') 

smallerdataset = open('smallerdataset.txt', 'w') 


for line in completedataset: 
    if 'trial1' in line: smallerdataset(line) 


completedataset.close() 
smallerdataset.close() 

我真的很喜歡做這樣的:

試驗=( 'trial12', 'trial23', 'trial34')

在completedataset行: 受審審判: 如果在線審判:smalldataset(行)

但這是行不通的。任何人都可以幫助我修改這個程序,使其正常工作?

+0

是否保證每個試驗發生在相應的行號上? (即第一行的'trial1',等等......)另外,每行是否爲固定長度?如果您可以粘貼數據集文件的一小部分樣本,可能會很有用。 – tzaman 2010-07-19 16:18:55

+0

我不願意分享文件的實際內容,但不幸的是沒有試用687例如655行。所以他們不匹配。 – 2010-07-19 17:23:36

回答

0

你將會碰到一些問題與您指定的方式你的試驗。如果您查找包含'trial1'的行,您還將獲得包含'trial123'的行。如果較大的數據集以某種方式構建,則可以嘗試在特定字段中查找試用編號。例如,如果數據是逗號分隔的,則可以使用csv包。最後,使用生成器表達式而不是循環會使事情變得更簡潔。假設試驗次數是你可以做一些你的數據集的第一列:

import csv 

trials = ['trial134', 'trial1', 'trial56'] 
data = csv.reader(open('completedataset.txt')) 

with open('smalldataset.txt','w') as outf: 
    csv.writer(outf).writerows(l for l in data if l[0] in trials) 
0

在我看來,你需要保存你感興趣的所有試驗編號的列表因此,也許你可以嘗試這樣的事情:

completedataset = open('completedataset.txt', 'r') 
smallerdataset = open('smallerdataset.txt', 'w') 

trials = [134, 274, 388] 
completedata = completedataset.readlines() 

for t in trials: 
    for line in completedata: 
     if "trial"+str(t) in line: 
      smallerdataset.write(line) 
completedataset.close() 
smallerdataset.close() 
0

你可能只是這樣做:

trials = ['trial1', 'trial134', 'trial274'] 

for line in completedataset: 
    for trial in trials: 
     if trial in line: smallerdataset(line) 

爲了更高效的操作,您可以將每行與'trial [0-9] +'-regex進行匹配,然後查看是否可以從一個集合中找到該符號。

+0

所以我首先嚐試了這個,因爲它看起來最簡單,並且它表示在連續字符後出現意想不到的字符並突出顯示':'。建議? – 2010-07-19 16:33:42

0

如果整個集合中的每個試驗都是已知字節大小,則可以使用file.seek(n),其中n是開始讀取的字節。例如,如果該文件中的每一行是3個字節長,你可以做一些事情,如:

myfile = open('file.txt', 'r') 
myfile.seek(lineToStartAt * 3) 

myfile.readline()#etc 

如果每行的字節數是可變的或未知的,你只需有行讀取並放棄你不關心(如KLee1's answer

0

假設你提前知道時間的試驗線,你可以做

trials = ('trial12', 'trial23', 'trial34') 

for line in completedataset: 
    for trial in trials: 
     if trial in line: smallerdataset(line) 
+0

所以我首先嚐試了這一個,因爲它看起來最簡單,它說行後續字符的意外字符並突出顯示':'。建議? – 2010-07-19 16:34:55

+0

我真的很喜歡這樣做....任何人都可以幫忙嗎? – 2010-07-19 21:34:37

+0

哪個':'突出顯示?就像Haukur所建議的那樣,這聽起來就像在行尾有一個反斜槓。我真的不知道如果沒有真正查看代碼,我可以做些什麼來提供幫助。 – MikeD 2010-07-20 14:45:12

0

假設你有一個功能,在看一條線,能告訴你該行是否是「被期望」 ,爲您的代碼正確的結構將是非常簡單的:

with open('completedataset.txt', 'r') as completedataset: 
    with open('smallerdataset.txt', 'w') as smallerdataset: 
     for line in completedataset: 
      if iwantthisone(line): 
       smallerdataset.write(line) 

with陳述照顧閉幕的爲您服務。在Python 2.7中,您可以將兩個with合併爲一個;在Python 2.5中,您需要使用from __future__ import with_statement啓動模塊;在Python 2.6中,目前最普遍的版本,上面的代碼是正確的形式。

因此,絕對一切都歸結爲iwantthisone函數。你不會告訴我們任何有關你線條的格式,使我們無法爲你提供更多幫助。但是,舉例來說,每行中的第一個單詞標識測試,例如test432 ...,並且您有一組名稱爲want_these的測試的編號,例如set([113, 432, 251, ...])。然後,寫iwantthisone一個非常簡單的方法可能是:

def iwantthisone(line): 
    firstword = line.split(None, 1)[0] 
    testnumber = int(firstword[4:]) 
    return testnumber in want_these 

iwantthisone正確的內容完全取決於你的線條的格式,你如何知道什麼行,你居然要保留的,當然。但我希望這個總體結構仍然有幫助。

注意,真的有這個一般結構,我建議沒有嵌套的循環 - )

0

關於您在您的評論顯示錯誤消息:續行字符是一個反斜槓,因此它告訴你,你在該行的某處有一個錯誤的反斜槓字符。

0

假設行總是以試用標識符開始,那麼您可以使用startswith函數和過濾器來提取所需的行。

completedataset = open('completedataset.txt', 'r') 
smallerdataset = open('smallerdataset.txt', 'w') 

wantedtrials = ('trial134', 'trial274', 'trial388') 

for line in completedataset: 
    if filter(line.startswith, wantedtrials): 
     smallerdataset.write(line)