在一个字符串中查找元音字母的数量

3

I have a string of letters as input.
input:

my_str = 'soumendra_in_stackoverflow'

我想要以下输出。其中所有元音字母应与它们在字典中的对应计数一起打印。
所需输出:

{'a': 2, 'e': 2, 'i': 1, 'o': 3, 'u': 1}

为此,我编写了以下程序:

对于这个问题,我编写了以下程序:

ans_dict = {}
for letter in my_str:
    if letter in ['a', 'e', 'i', 'o', 'u']:
        ans_dict[letter] = ans_dict.get(letter, 0) + 1
print(ans_dict)

它有效。然而,如何在单行中编写相同的逻辑(可能使用字典推导),而不使用collections.Counter
我尝试了这个,但是它失败了。

{x: + 1 for x in a if x in ['a', 'e', 'i', 'o', 'u'] }

3
为什么不使用 Counter?它看起来是最好的工具。虽然你可以使用字典推导完成,但结果是你需要对字符串进行五次迭代,使其变得不那么高效。 - Willem Van Onsem
请查看第一和第二个答案。他们提供了在列表中找出以元音字母开头的单词的方法。 - user9807244
请查看第一和第二个答案:https://dev59.com/ZmnWa4cB1Zd3GeqP03Ub - user9807244
https://dev59.com/ZmnWa4cB1Zd3GeqP03Ub - user9807244
1
@Gozzah:我认为这些链接的问题解决了不同的问题:在这里,我们关心的是字符串中元音字母的数量,而不是以元音字母开头的列表中的字符串!是的,有一些重叠,但从严格意义上讲,这两个问题是“不同”的。 - Willem Van Onsem
我相信如果您使用集合(set)进行查找,配合in运算符,速度会更快。 - N Chauhan
1个回答

7

您可以使用str.count,因此可以使用以下方式编写字典推导式:

result = { v: my_str.count(v) for v in "aeiou" }

但是这样会导致对my_str进行五次枚举。就像@DSM所说,.count(..)通常运行得相当快(我猜测它是在解释器级别实现的,因此不必"迭代"整个集合)。
个人认为,使用Counter更好,因为:
  1. 它专门为计数目的而设计,而且将数据封装到一种接口中,可以强制执行约束(除非Counter存在漏洞,否则计数一定是正确的,而自定义算法仍然可能出现"愚蠢"错误,虽然在这里很少见,但还是最好避免);以及
  2. 它提供了一个良好的接口来对这些计数做各种事情(例如counter1 & counter2将构建一个新的Counter,其中每个元素的计数都是最小值)。

3
注意强调“五”可能是错误的重点;在少量键时,使用count实际上更有效率。仅在五个键时,在长字符串上快了约一个数量级。概念上的争议更大(尽管即使在这里,当数量趋近极限时也会变得模糊——例如,我们都会写some_str.count(",")而不是Counter(some_str)[","])。 - DSM
1
@DSM:我认为.count(..)确实更快,因为它是在解释器级别上实现的(Python字符串的定义)。但如果我们不必要地对集合进行“多次迭代”,我并不是很喜欢这种方法 : )。从“大O”角度来看,它的规模将按*O(m n)*缩放,这意味着如果我们需要计算的字符数量相当大(例如所有中文Unicode字符),它将导致瓶颈。但您正确,对于元音字母,这可能会更快,或者差异微不足道)。 - Willem Van Onsem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接