【问题标题】:Shorten/DRY this python if statement? [closed]缩短/干燥这个 python if 语句? [关闭]
【发布时间】:2012-11-28 14:18:33
【问题描述】:
if a == arg:
    if arg not in a_list:
        do_something(arg)
elif b == arg:
    if arg not in b_list:
        do_something(arg)
else:
    do_something_else(arg)

提出一种惯用的方法来缩短和特别干燥上述语句 - 而不将其部分提取到单独的函数中。

编辑:有趣 ;-) 这不是家庭作业,也不是审查我的代码的请求,也许如果我将上面的内容重新构建如下,我的意图会变得更加清晰:

在 if 语句之上编写的 Python 方式是什么?我觉得我错过了一些东西,也许可以利用 python 中的和/或运算符?不将它的任何部分提取到单独的函数的原因是,这个问题更多的是关于重构而不是惯用的 pythonian if-logic。

【问题讨论】:

  • 它可以是一个你得到 "X" 和 "X_list" 的函数吗?还是你总是有 a,b,a_list,b_list ? match到底在做什么? ab 是什么类型的对象?
  • “不将其部分提取到单独的函数中” – 为什么?
  • "extracting parts of it to separate functions" == DRY
  • @InbarRose 谢谢你的问题,我已经编辑了文本以反映方法和类型无关紧要。

标签: python logic


【解决方案1】:

这是一个简单的答案:

for i, i_list  in [(a, a_list), (b, b_list)]:
    if i == arg:
        if arg not in i_list:
            do_something(arg)
        break
else:
    do_something_else(arg)

aa_listbb_list 组合成元组,我们可以更轻松地迭代它们。 然后是迭代本身的简单问题,匹配条件并运行所需的功能..

Python 支持for....else 语句。

如果 for 循环中没有返回或中断,则 else 语句将运行。

在这里,如果我们得到了我们想要的匹配,循环就会中断,我们就完成了。如果我们从不中断,那么我们将进入我们的 else 循环。在我看来,这是最Pythonic的方式。

编辑

为了使这更好,您应该在某种字典中包含a, b, a_list, b_list,其中d[a] = a_list

然后你可以像这样遍历字典:

for k, v  in d.items():
    if k == arg:
        if arg not in v:
            do_something(arg)
        break
else:
    do_something_else(arg)

这几乎是一样的,但看起来更好,你可以提前整理好你所有的ab和列表。

【讨论】:

  • 谢谢,这正是我正在寻找的答案类型!感谢您的时间 InbarRose
  • 我认为有些不同。如果b == argb in b_list 那么你的代码将调用do_something_else 但原始代码不会做任何事情。
  • @Igor 你是对的。我稍后会解决这个问题。 - 它是固定的。
【解决方案2】:
def run_for_match(candidate, patterns, search_lists, handlers, default_handler):
    for pattern, search_list, handler in zip(patterns, search_lists, handlers):
        if match(pattern, candidate):
            if candidate not in search_list:
                handler(candidate)
            break
    else:
        default_handler(candidate)

run_for_match(string, [a, b], [a_list, b_list], [do_something, do_something], do_something_else)

尽管将其放入封装patternssearch_listshandlersdefault_handler 的对象中非常有意义。比如:

class StringHandlerManager(object):

    def __init__(self, default_handler):
        self.handler_registry = []
        self.default_handler = default_handler

    def add_handler(self, pattern, search_list, handler):
        self.handler_registry.append((pattern, search_list, handler))

    def __call__(self, candidate):
        for pattern, search_list, handler in self.handler_registry:
            if match(pattern, candidate):
                if candidate not in search_list:
                    handler(candidate)
                break
        else:
            default_handler(candidate)

handle_string = StringHandlerManager(do_something_else)
handle_string.add_handler(a, a_list, do_something)
handle_string.add_handler(b, b_list, do_something)
handle_string(string)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2016-09-07
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多