2012-04-09 9 views
1
Imはアセンブラプログラムに取り組んおよびC上のPythonを使用することにしました(主な原因Pythonはリストで何ができるかを、私はそれを学びたいと思っ)

分割ラインタプルのPython

私の質問は、どのようにタプルの一部にテキストファイルの各行を分割するのですか?

例えば、テストファイルは次のとおりです。

ADD R1,R2; 
OR R1,R3; 

とそれはまた、セミコロンの後にコメントを無視しなければならない。この

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

にそれを解析するためのコードを持っています。ありがとう!

+0

Cのバックグラウンドに由来するPythonはちょっと変わったようです。私は、forループを使用して、リストの各要素(1行)を分割してみました。私も複数のデリミタ分割を試みましたが、それを実行することができませんでした。これまで私がやらなければならなかったプログラムは、5段階パイプラインアーキテクチャシミュレータでした。私はPythonをより良く知ってほしいと思っています。 –

答えて

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

より正確には、リスト。 –

+0

ああ、そうです!ありがとう@ Li-aungYip。 –

+0

これはすごくうまくいくのですが、その理由を理解しています。ありがとう! –

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 

ところで、私のバリアントが悪いわけではない、少し遅くなるものの

+0

なぜ 're.split'を使って引数なしで' str.split'のデフォルト動作を得るのですか?また、文字列を最初に 'strip()'する必要はありません。 –

+0

いいえ、 'string.split'はカンマではなくスペースだけを分割します。分割する前にすべて 'replace( '、'、 '')'を実行しますが、私はregexpを使って別の実装を提案します – San4ez

1

あなたのソースは次のことができ、この形式で

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

ある場合splitlines()を使ってソースを線形に分割し、次に区切り文字としては ';'

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

また、各ASMソース行をOPコードおよび個々のオペランドとして分割することもできます。

[[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

アセンブリのコメントは行の最初のセミコロンで始まります。ここで '[:-1]'の代わりに '[0]'を使うべきです。 –

+0

@Karl Knechtel ??? – ChessMaster

+0

';'で分割すると、最初のセミコロンの前のすべてが実際に必要なものになります。あなたの例の文字列では、 'OR R1、R3;'は実際には ';'の後に現れるのでコメントです。 Pythonでは ';' == '#'を使うので改行が必要です。 –

1

のようなものになるだろう。

ファイルの各行にトークンのリストが必要です。

トークンは、最初のセミコロンの後にすべてを切り取り、残りをコンマまたは空白のいずれかで分割した結果です。コンマをスペースで置き換え、空白で分割するだけで、これを行うことができます。

標準ライブラリを参照してください。文字列のメソッドsplitは、分割するものを与えないと空白で分割されます。メソッドを使用すると、1つの部分文字列を別の部分文字列に置き換えることができます(たとえば、','' ')。セミコロンの後にすべてのものを削除し、我々はそれ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を使用してください。実際には要素のリストを作成するのが実際の目的ではない場合、これはあまり明確ではありません。