2016-11-19 98 views
-1

我有一個文本文件描述了電子電路和其他一些事情。我已經構建了一個簡單的Python代碼,將文件拆分成不同的單元,然後可以根據需要進一步分析。 仿真語言的語法定義爲包含以下行內這些單位:Python中文件解析的功能方法

subckt xxx ..... 
... 
... 
ends xxx ... 

有幾個這樣的「文本塊」和其他的東西,我解析或離開了 - 比如註釋行。

要做到這一點,我用下面的核心:

with open('input') as f: 
    for l in iter(f): 
     if 'subckt' not in l: 
      pass 
     else: 
      with open('output') as o: 
       o.write(l) 
       for l in iter(f): 
        if 'ends' in l: 
         o.write(l) 
         break 
        else: 
         o.write(l) 

(不易粘貼實際的代碼,有可能是疏忽)

關於它的好處是,iter(f)當我到達subcktends行時,我一直在掃描文件,所以當我跳出內部循環時,外部循環繼續從該點開始,在隨後的行中搜索新出現的記號subckt

我在尋找關於如何將if/then子句的森林轉化爲更多功能的建議和/或指導,即基於只產生值(文件行或行)的「純」功能,然後將其組合成帶來最終結果。

具體而言,我不知道如何處理generator\map\filter實際上應該產生不同的行的事實,因爲它已發現subckt令牌或不。 我能想到的形式的filter的:

line = filter(lambda x: 'subckt' in x, iter(f)) 

但這當然只是給我哪裏該字符串是存在的線,而我想 - 從那一刻起 - yield所有線,直到找到ends令牌。 這是我必須處理遞歸?或者itertools.tee

在我看來,我所希望的是擁有某種形式的狀態,即「你已經達到一個子包」,但不訴諸真實的狀態變量,這將違背功能範式。

回答

2

不知道這是你在找什麼。 blocks(f)是在您的文件f中生成塊的生成器。每個塊都是'subckt'和'ends'之間的迭代器。如果你想在這個塊中包含這兩行,你需要在_blocks中做更多的工作。但我希望這給你一個想法:

def __block(f): 
    while 'subckt' not in next(f): pass # raises StopIteration at EOF 
    return iter(next(iter([])) if 'ends' in l else l.strip() for l in f) 

def blocks(f): 
    while 1: yield __block(f) # StopIteration from __block will stop the generator 

f = open('data.txt') 
for block in blocks(f): 
    # process block 
    for line in block: 
     # process line 

next(iter([])) if是一個小黑客終止理解/發電機。

+0

謝謝@schwobaseggl,這當然是我所問的。 我有一個稍微不同的解決方案,我將以aswer的形式發佈:如果您對此發表評論,我將不勝感激。 –

0

這個答案也適用,還是很熱衷於聽意見:

from itertools import takewhile, dropwhile 

def start(l): return 'subckt' not in l 
def stop(l): return 'ends' not in l 

def sub(iter):  
    while True:  
     a = list(dropwhile(start,takewhile(stop,iter)))  
     if len(a): 
      yield a 
     else: 
      return 
f = open('file.txt') 
for b in sub(f): 
    #process b 
f.close() 

東西我不能工作了沒有:在輸出封裝(含ends關鍵字)的最後一行。