1

クラスで初歩的な FSM を作成する必要があり、Python で作成しています。この割り当てでは、マシンのトランジションをテキスト ファイルから読み取る必要があります。したがって、たとえば、3 つの状態を持つ FSM で、それぞれに 2 つの可能な遷移があり、可能な入力が 'a' と 'b' の場合、次のようなテキスト ファイルが作成されます。

2          # first line lists all final states
0 a 1
0 b 2
1 a 0
1 b 2
2 a 0
2 b 1

入力値を文字列として保持しながら、一度に1行ずつ読み取り、状態をintに変換する、よりpythonicな方法を考え出そうとしています。基本的に、これはアイデアです:

self.finalStates = f.readline().strip("\n").split(" ")
for line in f:
  current_state, input_val, next_state = [int(x) for x in line.strip("\n").split(" ")]

もちろん、int("a") しようとすると、ValueError がスローされます。従来のループを使用して ValueError をキャッチできることはわかっていますが、より Pythonic な方法でこれを行うことを望んでいました。

4

4 に答える 4

12

実際には、整数であると予想されるトークンのみを解析しようとする必要があります

for line in f:
    tokens = line.split(" ")
    current_state, input_val, next_state = int(tokens[0]), tokens[1], int(tokens[2])

おそらくより読みやすい:

for line in f:
    current_state, input_val, next_state = parseline(line)

def parseline(line):
    tokens = line.split(" ")
    return (int(tokens[0]), tokens[1], int(tokens[2]))
于 2009-10-20T20:37:19.943 に答える
4

これは非常に機能的なものですが、「pythonic」かどうかはわかりません...そして、頭を悩ませる人もいるかもしれません。多数の値がある場合、この方法でそれを行うには、実際には「怠惰な」zip() が必要です。

types = [int, str, int]
for line in f:
   current_state, input_val, next_state = multi_type(types, line)

def multi_type(ts,xs): return [t(x) for (t,x) in zip(ts, xs.strip().split())]

また、ここではデフォルトが機能するため、strip と split に使用する引数は省略できます。

編集: 再フォーマット - 実際のコードでは 1 つの長い行として使用しません。

于 2009-10-20T20:38:03.530 に答える
1

問題によく一致する優れた回答が得られました。ただし、他の場合では、実際にいくつかのフィールドをint可能であれば (つまり、それらがすべて数字の場合)に変換し、strそれ以外の場合 (質問のタイトルが示すように)をどのフィールドかを事前に知らに残したい場合があります。はintであり、そうでないものはどれですか。

従来の Python のアプローチは、try/except... です。

def maybeint(s):
  try: return int(s)
  except ValueError: return s

...式(リスト内包表記など)でtry/exceptを実行する方法がないため、関数にラップする必要があります。したがって、次のように使用します。

several_fields = [maybeint(x) for x in line.split()]

ただし、必要に応じて、この特定のタスクをインラインで実行することできます。

several_fields = [(int(x) if x.isdigit() else x) for x in line.split()]

if/ 「三項演算子」はelse少し奇妙に見えますが、慣れることができます;-); 文字列のisdigitメソッドは、文字列が空ではなく、数字しかない場合に True を返します。

繰り返しますが、これは、入力タイプの特定のパターンを知っている特定のケースで行うべきことではありませんしかし、事前にそのような正確な情報を持っていない、より一般的な状況では適切かもしれません!intstrint

于 2009-10-21T01:44:49.150 に答える
0
self.finalStates = [int(state) for state in f.readline().split()]

for line in f:
    words = line.split()
    current_state, input_val, next_state = int(words[0]), words[1], int(words[2])
    # now do something with values

に短縮できることに注意してline.strip("\n").split(" ")くださいline.split()。のデフォルトの動作はstr.split()、任意の空白で分割することであり、先頭または末尾に空白がまったくない一連の単語を返します。

状態をループ内に変換している場合は、 も同様にしintたいと思います。finalStatesint

于 2009-10-20T23:03:33.757 に答える