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

发布于 2024-09-30 12:35:54 字数 370 浏览 2 评论 0原文

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

哪一种是首选解决方案?或者还有更好的吗?

I'm supposed to take a list of words and count all words in it which are 2 or more characters long and where the first and last character are equal.

I came up with two possible solutions:

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]])

Which one would be the preferred solution? Or are there even better ones?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一梦等七年七年为一梦 2024-10-07 12:35:55

在你的第二个例子中,如果你的 生成器表达式 会比 list-comp 更好名单很大。

sum(1 for word in words if len(word) >= 2 and word[0] == word[-1])

In your second example a generator expression would be better than list-comp if your list is large.

sum(1 for word in words if len(word) >= 2 and word[0] == word[-1])
划一舟意中人 2024-10-07 12:35:55

第一个肯定是 Python 中的首选解决方案。

不要忘记你的 Python 之禅:

Python 之禅,作者:Tim Peters

美丽总比丑陋好。

显式优于隐式。

简单总比复杂好。

复杂总比复杂好。

扁平比嵌套更好。

稀疏优于密集。

可读性很重要。

特殊情况还不够特殊
违反规则。

尽管实用性胜过纯粹性。

错误永远不应该悄无声息地过去。

除非明确沉默。

面对歧义,拒绝
猜测的诱惑。

应该有一个——而且最好是
只有一种显而易见的方法可以做到这一点。

虽然这种方式可能并不明显
首先除非你是荷兰人。

现在总比没有好。

尽管从来没有比
现在

如果实施起来有困难
解释一下,这是一个坏主意。

如果实现很容易
解释一下,这可能是个好主意。

命名空间是一个非常棒的主意
-- 让我们做更多这样的事情!

除此之外,你的解决方案都很好。

The first one would definitely be the preferred solution in Python.

Don't forget your Zen of Python:

The Zen of Python, by Tim Peters

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren't special enough to
break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the
temptation to guess.

There should be one-- and preferably
only one --obvious way to do it.

Although that way may not be obvious
at first unless you're Dutch.

Now is better than never.

Although never is often better than
right now.

If the implementation is hard to
explain, it's a bad idea.

If the implementation is easy to
explain, it may be a good idea.

Namespaces are one honking great idea
-- let's do more of those!

Other than that your solutions are good.

追风人 2024-10-07 12:35:55

我个人认为显式循环更具可读性,但这很大程度上取决于品味(有些人通常更喜欢较短的代码,尤其是当他们必须编写代码时)。

任一版本都可以进一步缩短/改进:

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])

I personally find the explicit loop more readable, but it's much a matter of taste (some prefer shorter code generally, especially when they have to write it).

Either version can be further shortened/improved:

result = 0
for word in words:
    result += int(len(word) >= 2 and word[0] == word[-1])
return result

The int() conversions is strictly speaking unnecessary, since True is a kind of 1, but it may be better for readability. The same approach can apply to the comprehension:

return sum(len(word) >= 2 and word[0] == word[-1] for word in words)

If you want to use len(), I'd point the reader to the fact that the values don't really matter:

len(1 for word in words if len(word) >= 2 and word[0] == word[-1])
枫以 2024-10-07 12:35:55

两者都相当不错。

有一些细微的差异:

列表理解返回您传递给 len 的另一个列表。第一个解决方案避免创建另一个列表。

Both are pretty good.

There are small differences:

List comprehension returns another list which you are passing to len. The first solution avoids creation of another list.

风渺 2024-10-07 12:35:55

您可能需要考虑的其他一些变体:

首先,您可以将过滤条件分解为函数。不管怎样,这个条件都很好,但如果它变得更复杂,我肯定会这样做:

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 会消耗并计算迭代器中的条目数,这是有意义的,但事实并非如此。

Some other variants you might want to consider:

First, you can break the filter condition into a function. This condition is fine either way, but if it becomes any more complex I'd definitely do this:

def check(word):
    return len(word) >= 2 and word[0] == word[-1]
sum(1 for word in words if check(word))

Next, if generating a list (as in the original list comprehension) is acceptable, then you can do this:

len(filter(check, words))

There's itertools.ifilter, but if you use that you need to use the sum expression again, so it doesn't end up any clearer.

The sum trick comes up so often that I'm surprised there isn't a standard library call to count the number of items in an iterator (if there is, I havn't found it). Alternatively, it'd make sense if len would consume and count the number of entries in an iterator if it has no __len__, but it doesn't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文