Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中文件解析的函数方法_Python_Functional Programming - Fatal编程技术网

Python中文件解析的函数方法

Python中文件解析的函数方法,python,functional-programming,Python,Functional Programming,我有一个描述电子电路的文本文件,还有一些其他的东西。我已经构建了一个简单的Python代码,它将文件分割成不同的单元,如果需要,可以进一步分析这些单元。 模拟语言的语法定义了以下行中包含的这些单位: subckt xxx ..... ... ... ends xxx ... 有一些“文本块”和其他我正在解析或省略的东西,比如注释行 为了实现这一点,我使用以下核心: with open('input') as f: for l in iter(f): if 'subckt

我有一个描述电子电路的文本文件,还有一些其他的东西。我已经构建了一个简单的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)
无法轻松粘贴真实代码,可能存在疏忽

它的好处是iterf一直在扫描文件,所以当我到达子循环的结束行时,我打破了内部循环,外部循环继续从该点开始,在后续行中搜索新出现的令牌子循环

我正在寻找关于如何将if/then子句林转换为更具功能性的内容的建议和/或指导,即基于“纯”函数,该函数只生成文件行或行的值,然后进行组合以获得最终结果

具体地说,我不知道如何处理generator\map\filter实际上应该根据它是否找到subckt标记生成不同的行这一事实。 我可以想到一个过滤器的形式:

line = filter(lambda x: 'subckt' in x, iter(f))
但是这当然只给了我字符串所在的行,而我想从那一刻起,放弃所有行,直到找到ends标记为止。 这是我必须处理的递归吗?或者是itertools.tee


在我看来,我想要的是某种形式的状态,即,你已经到达了一个子库,但没有诉诸于真正的状态变量,这将违背函数范式。

不确定这是否是你所寻找的。blocksf是生成文件f中的块的生成器。每个块都是“subckt”和“ends”之间行的迭代器。如果你想在块中包含这两行,你必须在_块中做更多的工作。但我希望这能给你一个想法:

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

nextiter[]if是终止理解/生成器的一个小技巧。

这个答案同样有效,仍然非常热衷于听取评论:

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关键字的最后一行。

谢谢@schwobasegll,这当然符合我的要求。我提出了一个稍有不同的解决方案,我将以问答的方式发布:如果您对此发表评论,我将不胜感激。