[英]Is there a Pythonic way to make this logic more elegant?
我是Python的新手,我一直在玩它来完成简单的任务。 我有一堆CSV需要以复杂的方式操作,但我为了学习Python而将其分解为更小的任务。
现在,给定一个字符串列表,我想删除字符串中任何名称的用户定义的标题前缀。 包含名称的任何字符串将仅包含名称,带有或不带标题前缀。 我有以下,它有效,但它感觉不必要的复杂。 是否有更多的Pythonic方法来做到这一点? 谢谢!
# 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)
[re.sub(r'^(Mr|Ms|Mrs)\.\s+', '', s) for s in test_csv_line]
假设prefixes
是可变的,可能是本地化的一个方面,或者你不想因为其他原因而不使用正则表达式,你可以做这样的事情(未经测试的代码):
def strip_title(string, prefixes):
for prefix in prefixes:
if string.startswith(prefix + ' '):
return string[len(prefix) + 1:]
return string
stripped = (list(strip_title(cell, prefixes) for cell in line)
for line in lines)
这不是特别有效,因为算法最终会进行大量冗余检查(例如,如果线以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_title
,它与前一个函数strip_title
,但是是为一组特定的前缀而构建的。 调用strip_title = TitleStripper(prefixes)
您可以调用strip_title(string)
。
主要是由于使用正则表达式,这将比第一种方法快一点,可能以牺牲清晰度为代价。
如果你真的只需要检查三个前缀,那么这些方法中的任何一个都是过度的,你应该使用另一个答案中解释的静态RE。
一个更Pythonic的方法是用else:
子句替换“end of list”检查到for item in line:
loop中的for item in line:
。 如果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
逻辑与你的逻辑相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.