缩短/干掉这个python if语句?

时间:2012-11-28 14:18:34

标签: python logic

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)

提出一种惯用的方法来缩短并明确地干掉上述陈述 - 而不是将其中的部分内容提取到单独的函数中。

编辑:有趣;-)这不是家庭作业,这也不是审查我的代码的请求,也许如果我在上面重构,我的意图变得更加明确:

什么是pythonian方式来编写上面的if语句,使得它对语言来说既干又习惯?我觉得我错过了一些东西,或许可以在python中使用和/或运算符?没有将它的任何部分提取为单独函数的原因是,这个问题更多的是关于重构而不是关于惯用的pythonian if-logic。

2 个答案:

答案 0 :(得分:2)

这是一个简单的答案:

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_listb以及b_list组合到元组中,我们可以更轻松地迭代它们。 然后它只是迭代本身的一个简单问题,匹配条件,并运行所需的函数..

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

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

在这里,如果我们得到我们想要的匹配,循环将会中断,我们就完成了。如果我们永远不会破坏,那么我们将进入我们的其他循环。在我看来,这是最常用的 Pythonic 方式。

修改

为了更好地做到这一点,你应该在a, b, a_list, b_list

的某种词典中加d[a] = a_list

然后你可以像这样迭代dict:

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

这几乎是一样的,但它看起来更好,你可以拥有所有ab,并列出所有已预先整理好的内容。

答案 1 :(得分:1)

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)