我有一个描述电子电路的文本文件以及其他一些用它做的事情。我已经构建了一个简单的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)
一直在扫描文件,所以当我到达内部循环时,当我到达ends
的{{1}}行时,外部循环继续从那一点开始,在后续行中搜索新出现的标记subckt
。
我正在寻找关于如何将subckt
子句的森林转换为更具功能性的东西的建议和/或指导,即基于'纯'函数,它只产生值(文件行或行)并且是然后组成以达到最终结果。
具体来说,我不确定如何处理if/then
实际上应该根据它找到generator\map\filter
令牌的事实产生不同行的事实。
我可以想到subckt
形式:
filter
但这当然只给出了字符串存在的行,而我希望 - 从那一刻开始 - line = filter(lambda x: 'subckt' in x, iter(f))
所有行,直到yield
令牌已找到。
这是我必须处理递归的东西吗?或者也许是ends
?
在我看来,我想要的是拥有某种形式的状态,即“你已经达到了一个子类”,但没有诉诸真正的状态变量,这将违背功能范式。
答案 0 :(得分: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
有点终止理解/生成器。
答案 1 :(得分: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
关键字)括在输出中。