列表理解和len()与简单for循环

时间:2010-11-02 23:46:27

标签: python list-comprehension

我应该取一个单词列表并计算其中长度为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]])

哪一个是首选解决方案?还是有更好的?

5 个答案:

答案 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__,那么它是有意义的,但它没有。