我必须在一个类中创建一个基本的FSM,并用Python编写它。分配要求我们从文本文件中读取机器的过渡。例如,一个具有3个状态的FSM,每个状态有2个可能的转换,可能的输入'a'和'b',wolud有一个如下所示的文本文件:
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
我试图想出一种更加pythonic的方式来一次读取一行并将状态转换为int,同时将输入值保持为字符串。基本上这就是这个想法:
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方法来实现这一点。
答案 0 :(得分: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]))
答案 1 :(得分:5)
这是非常实用的功能,但我不确定它是否是“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的参数,因为默认值在此处可用。
编辑:重新格式化 - 我不会将它用作实际代码中的一条长行。
答案 2 :(得分:1)
你得到了很好的答案,可以很好地解决你的问题。但是,在其他情况下,可能确实存在这样的情况:如果可行(例如,如果它们都是数字),您希望将某些字段转换为int
,否则将它们保留为str
(作为标题你的问题建议)没有提前知道哪些字段是整数,哪些字段不是。
传统的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。
重复一遍,这是不您在特定情况下应该做些什么,您知道具体的int
- str
- int
输入模式类型;但是在更普遍的情况下,你可能不适合提前获得如此准确的信息!
答案 3 :(得分: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
,我认为您希望finalStates
也是int
。