重构这些嵌套for / else循环的最pythonic方式(如果有的话)是什么?

时间:2014-01-15 03:24:09

标签: python for-loop coding-style refactoring nested-loops

我有一个函数可以检查字符串中的子字符串。根据字符串中找到的子字符串的类型,我调用一个唯一的函数并将其存储在变量x中。最后,该函数具有标准化的返回值,它对x执行几个复杂的操作,然后返回它。像这样:

def awesome(string):
    for substring in ['AB', 'CD', 'EF']:
        if substring in string:
            x = do_something()
            break
    else:
        for substring in ['12', '34', '56']:
            if substring in string:
                x = do_something_else()
                break
        else:
            for substring in ['!@', '@#', '#$']:
                if substring in string:
                    x = do_another_thing()
                    break
    # Universally modifies x
    x += complicated_thing()
    if some_condition(x):
        x += "Hello"
    else:
        x += "World"
    return x

最初有三个选择对我来说很明显:

  • 首先是保持原样。当然,嵌套的for / else循环有点难看。
  • 第二个选项是包含在每个x循环中普遍修改returnfor而不是break的代码块,但这似乎破坏了原则不要重复自己。
  • 最后,我可以在最新的函数function中保存最终的代码块,并在每个for循环中返回function(x),但这是否会创建一个几乎没有用的不必要的深奥函数?

任何建议表示赞赏。谢谢!

4 个答案:

答案 0 :(得分:3)

这个怎么样:

def check(substrings, somestring):
    return any(substring in somestring for substring in substrings)

def awesome(somestring):
    x = some_default_value
    vals = [do_something, do_something_else, do_another_thing]
    subs = [['AB', 'CD', 'EF'], ['12', '34', '56'], ['!@', '@#', '#$']]
    for val,substrings in zip(vals, subs):
        if check(substrings, somestring):
            x = val()
            break

    # Universally modifies x
    x += complicated_thing()
    if some_condition(x):
        x += "Hello"
    else:
        x += "World"
    return x

答案 1 :(得分:3)

def is_substr(input_string, substrs):
    return any(strs in input_string for strs in substrs)

def awesome(my_string):
    if is_substr(my_string, ["A", "B", "C"]):
        x = do_something() + complicated_thing()
    elif is_substr(my_string, ["1", "2", "3"]):
        x = do_something_else() + complicated_thing()
    elif is_substr(my_string, ["!", "#", "$"]):
        x = do_another_thing() + complicated_thing()
    return x + ("Hello" if some_condition(x) else "World")

如果检查的顺序无关紧要,可以进一步推广和挤压

def awesome(input_string):
    functions_dict = {
        ('AB', 'CD', 'EF'): do_something,
        ('12', '34', '56'): do_something_else,
        ('!@', '@#', '#$'): do_another_thing
    }
    for sub_strings, function in functions_dict.items():
        if any(s in input_string for s in sub_strings):
            x = function() + complicated_thing()
            return x + ("Hello" if some_condition(x) else "World")

答案 2 :(得分:2)

这也应该有用。

def awesome(string):

    foo = [{'subs': ['A', 'B', 'C'], 'func': do_something},
           {'subs': ['1', '2', '3'], 'func': do_something_else},
           {'subs': ['!', '?', '.'], 'func': do_another_thing}
    ]

    for bar in foo:
        if any(s in string for s in bar['subs']):
            x = bar['func']()
            break

    # Universally modifies x
    x += complicated_thing()
    if some_condition(x):
        x += "Hello"
    else:
        x += "World"
    return x

答案 3 :(得分:0)

一个简单的选项是

id="txtjs"