我应该取一个单词列表并计算其中长度为2个或更多字符并且第一个和最后一个字符相等的所有单词。
我提出了两种可能的解决方案:
result = 0
for word in words:
if len(word) >= 2 and word[0] == word[-1]:
result += 1
return result
VS
return len([word for word in words if len(word) >= 2 and word[0] == word[-1]])
哪一个是首选解决方案?还是有更好的?
答案 0 :(得分:14)
在你的第二个例子中,如果你的列表很大,generator expression会比list-comp更好。
sum(1 for word in words if len(word) >= 2 and word[0] == word[-1])
答案 1 :(得分:4)
第一个肯定是Python中的首选解决方案。
不要忘记你的禅宗:
Python的禅宗,Tim Peters
美丽胜过丑陋。
明确比隐含更好。
简单比复杂更好。
复杂比复杂更好。
Flat比嵌套更好。
稀疏比密集更好。
可读性很重要。
特殊情况不够特别 打破常规。
虽然实用性胜过纯洁。
错误不应该默默地传递。
除非明确沉默。
面对模糊,拒绝 诱惑猜测。
应该有一个 - 最好是 只有一个 - 明显的方式来做到这一点。
虽然这种方式可能并不明显 起初,除非你是荷兰人。
现在比永远好。
虽然从来没有经常好过 正确现在。
如果实施很难 解释一下,这是一个坏主意。
如果实施容易 解释一下,这可能是一个好主意。
命名空间是一个很棒的主意 - 让我们做更多的事情!
除了你的解决方案是好的。
答案 2 :(得分:2)
我个人认为显式循环更具可读性,但这很重要(一些人更喜欢较短的代码,特别是当他们必须编写代码时)。
任何一个版本都可以进一步缩短/改进:
result = 0
for word in words:
result += int(len(word) >= 2 and word[0] == word[-1])
return result
int()转换严格来说是不必要的,因为True是一种1,但它对于可读性可能更好。同样的方法可以适用于理解:
return sum(len(word) >= 2 and word[0] == word[-1] for word in words)
如果你想使用len(),我会向读者指出这些值并不重要:
len(1 for word in words if len(word) >= 2 and word[0] == word[-1])
答案 3 :(得分:1)
两者都很不错。
存在细微差别:
列表理解返回另一个传递给 len 的列表。第一种解决方案避免创建另一个列表。
答案 4 :(得分:1)
您可能需要考虑的其他一些变体:
首先,您可以将过滤条件分解为函数。这种情况无论如何都可以,但如果它变得更复杂,我肯定会这样做:
def check(word):
return len(word) >= 2 and word[0] == word[-1]
sum(1 for word in words if check(word))
接下来,如果生成列表(如原始列表理解中)是可接受的,那么您可以这样做:
len(filter(check, words))
有itertools.ifilter,但是如果你使用它,你需要再次使用sum
表达式,所以它不会更清晰。
sum
技巧常常出现,我很惊讶没有标准的库调用来计算迭代器中的项目数(如果存在,我找不到它)。或者,如果len
消耗并计算迭代器中的条目数(如果它没有__len__
,那么它是有意义的,但它没有。