这很难理解(在我看来),所以我想知道是否有人可以用更短的行建议一些更 Pythonic 的东西?
一般来说,pythonic 并不意味着较短的行。 Pythonic 代码应该易于阅读和遵循(至少有一点背景知识)。因此,如果您觉得难以阅读,您可以将其分解为不同的功能:
# I'm not sure if the function name is a good fit, it's just a suggestion.
def contains_at_least_one(data, words):
for word in words:
if word in data:
return True
return False
def is_important(data_row):
if data_row.get('important', None):
return True
add_data = get_additional_data(data_row).lower()
if contains_at_least_one(add_data, NEGATIVE_WORDS):
return False
if contains_at_least_one(add_data, POSITIVE_WORDS):
return True
return False
我可以合并两个 for 循环吗?
不是真的。因为NEGATIVE_WORDS 循环应该优先于(至少在您的代码中)POSITIVE_WORDS 循环。除了你的意思是把它分解成一个函数。那就先看看吧。
如果我合并两个 for 循环,会不会消耗更多时间?
我不确定你所说的“合并”循环是什么意思,但如果你想让它更短,你可以在上面的方法中使用any。它相当于for-loop 并且更短 - 但根据我和 StefanPochmans 的基准测试,它更慢:
def contains_at_least_one(data, words):
return any(word in data for word in words)
def is_important(data_row):
if data_row.get('important', None):
return True
add_data = get_additional_data(data_row).lower()
if contains_at_least_one(add_data, NEGATIVE_WORDS):
return False
if contains_at_least_one(add_data, POSITIVE_WORDS):
return True
return False
您甚至可以通过将and 用于return 来减少行数。我不会推荐它,因为这样的结构不会提高可读性,但这是你的决定,它是“缩短”代码的一种方法:
def is_important(data_row):
if data_row.get('important', None):
return True
add_data = get_additional_data(data_row).lower()
return (not contains_at_least_one(add_data, NEGATIVE_WORDS) and
contains_at_least_one(add_data, POSITIVE_WORDS))
有点牵强,但也许您甚至可以使用sets 来加快速度。这将要求您只查找整个单词匹配(不是部分匹配,不是多单词匹配):
def contains_at_least_one(data, words):
return data.intersection(words)
def is_important(data_row):
if data_row.get('important', None):
return True
add_data = set(get_additional_data(data_row).lower().split()) # set and split!
return not contains_at_least_one(add_data, NEGATIVE_WORDS) and contains_at_least_one(add_data, POSITIVE_WORDS)
如果您不希望标点符号破坏匹配,另请参阅 tobias_k 答案中的正则表达式建议。但是,设置方法仅表示“小建议”-我怀疑它是否可以应用于您的情况。但你需要判断。