【问题标题】:How to make if-elif conditionals shorter for parsing如何使 if-elif 条件句更短以进行解析
【发布时间】:2013-02-13 10:24:00
【问题描述】:

我正在尝试制作一个程序来执行某些用户输入的某些任务,例如递增或递减整数,将字符添加到字符串等。
用户可以在同一行中给出多个命令。

当我使用raw_input 时,我不能(也不想)接受多线输入。

是否可以使if-elif-else 条件句更短,但仍保持可读形式?

for i in test_str:
    if i == '[':
        a += 1
    elif i == '(':
        b += 1
    elif i == ']' and c > 0:
        c -= 1
    elif i == ')'and d > 0:
        d -= 1
    elif c == 0 and d == 0:
        ret += i
    ... # more elifs

elif 也有可能:

elif i == 'o':
    if test_str[test_str.index(i)+1] == i: # next char is same
         # handle
    else:
         # handle

我正在使用它进行解析。

【问题讨论】:

  • 对我来说它看起来足够短。而且它仍然可读。
  • 嗯,如果您可以扩展您正在共享的信息,这将有所帮助,就目前而言,在不了解更多信息的情况下,我看不出有任何真正的方法可以减少这种情况。一个建议是根据i 的值将字典映射到应该做什么。
  • 应用是什么?你是在写解析器还是大括号匹配器?
  • 我会说你可以简化你的算法,但是如果没有更多的上下文,这是不可能确定的。
  • @eumiro 对不起,忘了提,但还有更多 elif 声明

标签: python string parsing if-statement


【解决方案1】:

如果您想减少代码使用的行数,您可以在一行中简单地执行 if - elif - else 语句。

if i == '[':
    a += 1
elif i == '(':
    b += 1
elif i == ']' and c > 0:
    c -= 1
elif i == ')'and d > 0:
    d -= 1
elif c == 0 and d == 0:
    ret += i

变成:

if i == '[': a += 1   
elif i == '(': b += 1   
elif i == ']' and c > 0: c -= 1   
elif i == ')'and d > 0: d -= 1    
elif c == 0 and d == 0: ret += i

但你应该改变你正在使用的逻辑,而不是这样做。

首先,你应该使用一个函数,我也建议使用某种映射。

例子:

d = {
'[' : ('add', a, 1),
'(' : ('add', b, 1),
']' : ('method', my_method, ['sample_arg1', 'sample_arg2'], {'sample_kwarg' : 'sample value'})} 

def check_char(char, mapping):
    mapper = d.get(char, None)
    if mapper:
        if mapper[0] == 'add':
            mapper[1] += mapper[2]
        if mapper[0] == 'subtract':
            mapper[1] -= mapper[2]
        if mapper[0] == 'method':
            mapper[1](char, mapper[2], mapper[3])
    # you get the idea....

def my_method(char, *args, **kwargs):
    # deal with char....

【讨论】:

  • 我明白了,我不会为您编写代码,但您应该使用我的示例作为开始为您的代码编写适当的函数。进一步的建议是将它全部包装在一个类中,并为您可能拥有的每种组合/动作类型提供一个函数,将每种情况映射到其最通用的形式,然后您的界面将只是提供流、字符串或char 到你的函数中,它会做剩下的。 :)
  • 你能告诉我如何处理多个 elifs,使用地图,而不是代码,而只是一个开始,就像一个可以使用的想法。
  • 您可以将方法/函数映射到字典,因此您可以拥有d = {']' : my_method},然后在您的check_char 中,您可以通过执行mapper = d.get(char, None) 将您的输入发送到一个函数,如果mapper 是一个您只需调用它的函数:mapper(char)(就像在做 my_method(char) 一样)然后该函数将处理输入。 - 添加到我的答案中
  • 感谢映射器的想法。我知道单行 if 语句,但它们不是我想要的。但我得到了我似乎需要的东西。不过我没有看到任何更新:)
  • 刷新页面? - 我会为你添加一个奖金,带有参数的方法。给我一分钟。
猜你喜欢
  • 2022-11-23
  • 2020-01-05
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多