2012-04-09 55 views
1

进出口工作在一个汇编程序,并选择使用Python在C(主要是因为什么Python可以用列表做,我想了解它)分割线成的一部分元组的Python

我的问题是如何将文本文件的每一行分割成一个元组的一部分?

如测试文件是:

ADD R1,R2; 
OR R1,R3; 

,并有代码来解析成这个

UserProgram=[['ADD','R1','R2'],['OR','R1','R3']] 

它也将忽略分号后的意见。谢谢!

+0

从C背景的,巨蟒似乎有点陌生。可以预见的是,我尝试使用for循环来分割列表的每个元素(单行)。我也尝试了多个分隔符分割,但无法运行。在此之前我必须做的程序是一个5阶段流水线架构模拟器。希望我更好地了解Python,因为它看起来会让自己变得更好。 – 2012-04-09 16:04:18

回答

2
>>> s = "ADD R1,R2; OR R1,R3;" 
>>> t1 = s.split(';') 
>>> t1 
['ADD R1,R2', ' OR R1,R3', ''] 
>>> UserProgram = [t.strip().replace(',', ' ').split(' ') for t in t1 if len(t) > 0] 
>>> UserProgram 
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']] 
>>> 

顺便说一句,方括号表示列表,而不是元组。

+3

列出,更准确。 – 2012-04-09 06:58:05

+0

啊,是的!谢谢@ Li-aungYip。 – 2012-04-09 07:03:01

+0

这很好,我明白为什么。谢谢! – 2012-04-09 16:04:41

1
>>> import re 
>>> [re.split('\W+', s.strip()) for s in 'ADD R1,R2; OR R1,R3;'.split(';') if s] 
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']] 

UPD:

python -m timeit -s "import re; regexp = re.compile('\W+');" "[regexp.split(s.strip()) for s in 'ADD R1,R2; OR R1,R3;'.split(';') if s]" 
100000 loops, best of 3: 3.34 usec per loop 

python -m timeit "[t.strip().replace(',', ' ').split(' ') for t in 'ADD R1,R2; OR R1,R3;'.split(';') if t]"100000 loops, best of 3: 2.1 usec per loop 

BTW我的变种也不错,虽然有点慢

+0

为什么要使用're.split'来获取没有参数的'str.split'的默认行为?这也不要求你先“剥去”()该字符串。 – 2012-04-10 00:05:08

+0

不,'string.split'只会分割空格,而不是逗号。在分割之前,你都会'替换(',','')',但我建议使用正则表达式执行另一个实现 – San4ez 2012-04-10 05:44:06

1

如果你的来源是这种格式

source=""" 
ADD R1,R2; 
OR R1,R3; 
""" 

那么你就可以只需通过拆分线()拆分线性源,然后再用拆分作为分隔符丢弃';'后的任何内容

sourcelines=[x.split(";")[0].replace(',',' ').split() 
      for x in source.splitlines() if x] 
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']] 

您也可以继续前进,分裂每个ASM源代码行操作码和操作数个人。

[[token.split(',') for token in x.split(";")[0].split()] 
    for x in source.splitlines() if x] 

你会得到这样的事情

[[['ADD'], ['R1', 'R2']], [['OR'], ['R1', 'R3']]] 
0
>>>s = "ADD R1,R2; OR R1,R3;" 
>>>[substr.split() for substr in s.replace(',',' ').split(';')[:-1]] 
[['ADD', 'R1', 'R2'], ['OR', 'R1', 'R3']] 
+0

装配注释从行的第一个分号开始,而不是最后一个;你应该在这里使用'[0]'而不是'[:-1]'。 – 2012-04-10 00:06:41

+0

@Karl Knechtel ??? – ChessMaster 2012-04-10 06:00:24

+0

当你在第一个分号之前分隔';'时,就是你真正想要的。在你的例子中,'OR R1,R3;'实际上是一个注释,因为它出现在';'之后。 Python中的';'=='#',所以你需要一个换行符。 – 2012-07-25 13:52:21

1

因此,我们必须在该格式的源文件。

我们需要文件中每行的标记列表。

令牌是在第一个分号后切除所有内容的结果,并将剩下的分割为逗号或空格。我们可以通过用空格替换逗号,然后仅仅分割空格来实现。

所以我们转向标准库。字符串的split方法在您不给它分割的时候会在空白处分割。 replace方法让我们用另一个替换一个子字符串(例如,','' ')。到分号后除去一切,我们可以partition它并采取第一部分(结果的元素0)。*为个别线路的处理从而看起来像

line.partition(';')[0].replace(',', ' ').split() 

然后我们简单地做这对每行的文件。要获得将某些函数应用于源元素的结果列表,我们可以使用列表理解(基本上我们描述结果列表应该是什么样子)直接请求它。 Python中的文件对象是行的有效来源;你可以迭代它(C++程序员可能更熟悉这个概念),而元素是文件的行。

所以我们需要做的就是打开文件(我们将惯用使用with块,以管理文件),并生成列表:

with open('asm.s') as source: 
    parsed = [ 
     line.partition(';')[0].replace(',', ' ').split() 
     for line in source 
    ] 

完成。

*或再次使用split,但我觉得这是不太清楚时,它实际上不是你的目标是生产要素的列表。