使用Python解析嵌套循环的文件

时间:2014-03-11 13:22:54

标签: python python-2.7

目前,Python读取文件的每一行并执行函数doStep()。该函数传递给正在读取的行上的任何内容。

data.txt中

a
b
c
b

read.py

fin = open('data.txt')
for step in fin:
    doStep(step)

然后Python将执行

doStep(a)
doStep(b)
doStep(c)
doStep(b)

问题:如果我想在 data.txt 中定义嵌套循环,应该如何定义和解析?嵌套和循环迭代次数应在 data.txt

中定义

例如,通过阅读 data.txt 我想循环这5次

doStep('a')
doStep('b')
doStep('c')

并循环10次

doStep('x')
doStep('y')
doStep('z')

并重复所有内容3次(嵌套)。

5 个答案:

答案 0 :(得分:1)

您的文件中有一个简单的语法,目前为(<item>\n)*。解析这很容易,你只需逐行循环。

您现在希望增加语法的复杂性以包含循环。你如何做到这一点取决于你。您可能希望包含一个“跳转到行号n”的命令或某种包含重复的递归语法。

reading about EBNF开始。然后是read about writing a simple parser。你的将比那个例子简单得多。

你的语法可能如下:

file = file_item*
file_item = single_item | repeated_items
repeated_items = single_item*
single_item = [a-z]*

或者,您可以定义自己的数据结构(例如,作为Python类)来表示重复,并将其序列化(例如使用pickle)。然后,您可以反序列化并“回放”您的数据结构以检索输出。

答案 1 :(得分:1)

这只是一个例子,但有很多事情要做。

数据文件:

@5
a
b
c
@;
@10
x
y
z
@;

Python代码:

times = None
buffer = []
fin = open('data.txt')
for line in fin:
    if line[0] == '@':
        if line[1] == ';':
            for step in buffer * times:
                doStep(step)
            times = None
            buffer = []
            continue
        times = int(line[1:])
        continue
    if times:
        buffer.append(line)
    else:
        doStep(line)

这个解决方案通常比解析更糟糕,但对于一个非常简单的任务来说它仍然是一个非常简单的(示例)解决方案(除非你希望概括它,它可能会这样做)。

答案 2 :(得分:1)

实现循环的最简单方法是执行像标签/循环操作一样简单的操作。 我会使用与您的数据不冲突的语法。

.. label1
a
b
c
-- label1 5
d
.. label2
x
y
z
-- label2 10

在阅读文件时,我会跟踪文件中的当前位置并跟踪所有标签。堆栈可用于保存每个循环的计数器(处理嵌套循环)。

当找到循环时,如果堆栈为空,则在其上放置迭代次数和循环位置,并寻找标签位置。如果堆栈不为空,则弹出最后一个值并减小它。如果它不是0,则把它放回堆栈。

答案 3 :(得分:1)

您可以将迭代编号放在第一行,将数据放在其后:

data.txt中:

5, a, b, c
10, x, y, z

并使用split来解析字符串:

with open('data.txt') as fin:
    for line in fin:
        l = line.split(', ')
        n, steps = l[:1], l[1:]
        for _ in range(n):
            for step in steps:
                doStep(step)

答案 4 :(得分:1)

您可以使用普通的data.py文件代替data.txt文件。 在那里你可以从你的read.py导入例程,并用所有的python魔法执行funktions / methodes。