有没有一种Pythonic方法可以让这个逻辑更加优雅?

有没有一种Pythonic方法可以让这个逻辑更加优雅?,python,Python,我是Python新手,我一直在为简单的任务使用Python。我有一堆CSV,需要以复杂的方式进行操作,但为了学习Python,我将这些CSV分解成更小的任务 现在,给定一个字符串列表,我想删除字符串中任何名称的用户定义标题前缀。任何包含名称的字符串将只包含名称,包括或不包括标题前缀。我有以下几点,它是有效的,但它只是觉得不必要的复杂。有没有更像蟒蛇的方法?谢谢 # Return new list without title prefixes for strings in a list of st

我是Python新手,我一直在为简单的任务使用Python。我有一堆CSV,需要以复杂的方式进行操作,但为了学习Python,我将这些CSV分解成更小的任务

现在,给定一个字符串列表,我想删除字符串中任何名称的用户定义标题前缀。任何包含名称的字符串将只包含名称,包括或不包括标题前缀。我有以下几点,它是有效的,但它只是觉得不必要的复杂。有没有更像蟒蛇的方法?谢谢

# Return new list without title prefixes for strings in a list of strings.
def strip_titles(line, title_prefixes):
    new_csv_line = []
    for item in line:
        for title_prefix in title_prefixes:
            if item.startswith(title_prefix):
                new_csv_line.append(item[len(title_prefix)+1:])
                break
            else:
                if title_prefix == title_prefixes[len(title_prefixes)-1]:
                    new_csv_line.append(item)
                else:
                    continue
    return new_csv_line

if __name__ == "__main__":
    test_csv_line = ['Mr. Richard Stallman', 'I like cake', 'Mrs. Margaret Thatcher', 'Jean-Claude Van Damme']
    test_prefixes = ['Mr.', 'Ms.', 'Mrs.']
    print strip_titles(test_csv_line, test_prefixes)

假设
前缀
是可变的,可能是本地化的一个方面,或者您出于其他原因不喜欢使用正则表达式,您可以这样做(未测试的代码):

这不是特别有效,因为算法最终会执行大量冗余检查(例如,如果行以
M
开头,则检查三次)。这类事情是使用正则表达式的一个重要原因

或者,您可以动态构建正则表达式,方法是转义每个前缀并将它们与
分支连接:

def TitleStripper(prefixes):
    import re
    escaped_titles = (re.escape(prefix) for prefix in prefixes)
    prefix_re = re.compile('^({0}) '.format('|'.join(escaped_titles)))
    def strip_title(string):
        return prefix_re.sub('', string, 1)
    return strip_title
函数
TitleStripper
创建一个闭包函数
strip\u title
,该函数的工作原理与前一个函数类似,但它是为一组特定的前缀构建的。调用
strip\u title=TitleStripper(前缀)
后,您只需调用
strip\u title(string)

主要是由于使用了正则表达式,这将比第一种方法快一点,可能是以牺牲清晰度为代价的


如果您真的只需要检查三个前缀,那么这两种方法中的任何一种都是多余的,您应该像另一个答案中所解释的那样使用静态RE。

一种更为通俗的方法是将“列表结束”检查替换为
行中的
项的
子句。如果for循环在不中断的情况下完成,则执行
else

# Return new list without title prefixes for strings in a list of strings.    
def strip_titles(line, title_prefixes):
    new_csv_line = []
    for item in line:
        for title_prefix in title_prefixes:
            if item.startswith(title_prefix):
                new_csv_line.append(item[len(title_prefix)+1:])
                break
        else:
            new_csv_line.append(item)
    return new_csv_line

在其他方面,逻辑与您的相同。

Wow。很酷。但是,当去掉前缀时,它确实会在名称前留下一个空格。我永远不会厌倦看到正则表达式的美妙之处。@paracaudex:你可能在评论时看到了我的第一个版本。目前的版本去掉了前缀后面的所有空格。仍然有许多书呆子[缩写有,缩写没有]和击键节俭的人和讨厌Ms的人在周围。。。“Jane Doe女士”、“Betty Bloggs女士”、“Fred Nerk先生”和“Hildegarde Higgs小姐”怎么样?幸好这不是一个问题,因为数据来自另一个来源,对此有一个一致的方案。“一致的数据源”?我将在“著名的遗言”下归档:-)为什么我需要转义每个前缀?例如,您需要转义一个
,即替换
\.
,以便它不匹配任何字符。你可以这样做。啊,我明白了。我以为你的意思是逃避整个事情-比如\先生,我没有意识到re有逃避功能。
def TitleStripper(prefixes):
    import re
    escaped_titles = (re.escape(prefix) for prefix in prefixes)
    prefix_re = re.compile('^({0}) '.format('|'.join(escaped_titles)))
    def strip_title(string):
        return prefix_re.sub('', string, 1)
    return strip_title
# Return new list without title prefixes for strings in a list of strings.    
def strip_titles(line, title_prefixes):
    new_csv_line = []
    for item in line:
        for title_prefix in title_prefixes:
            if item.startswith(title_prefix):
                new_csv_line.append(item[len(title_prefix)+1:])
                break
        else:
            new_csv_line.append(item)
    return new_csv_line