我儿子刚上高中,在数学课上,他被要求做一些统计作业。练习是在一段文字中计算所有元音,然后回答一些有关频率的问题。


text = "Australian Rules Football is a ball game played by two teams of eighteen players with an ellipsoid ball on a large oval field with four upright posts at each end. Each team attempts to score points by kicking the ball through the appropriate posts (goals) and prevent their opponents from scoring. The team scoring the most points in a given time is the winner. Usually this period is divided into four quarters of play.Play begins at the beginning of a quarter or after a goal, with a tap contest between two opposing players (rucks) in the centre of the ground after the umpire either throws the ball up or bounces it down."

vowels = {'a':0, 'e':0, 'i':0, 'o':0, 'u':0}

for t in text:
    if t.lower() == 'a':
        vowels['a'] = 1 + vowels['a']
    elif t.lower() == 'e':
        vowels['e'] = 1 + vowels['e']
    elif t.lower() == 'i':
        vowels['i'] = 1 + vowels['i']
    elif t.lower() == 'o':
        vowels['o'] = 1 + vowels['o']
    elif t.lower() == 'u':
        vowels['u'] = 1 + vowels['u']

print vowels


我并不是说Python很好。我喜欢混帐,但我想我在这里遗漏了一些东西。该脚本可以工作,但是我显然在for循环中重复自己。对我来说,“ Pythonic”做得更好吗?

评论

在文档中查找collections.Counter-这就像一个字典,但也提供了类似于most_common(n)的操作,该操作返回n个最常见(计数最高)条目的有序列表。

与String Python中的Count Vowels几乎相同

#1 楼


降低一次:在循环内用text.lower()代替t.lower()
t in vowels检查字符是否是元音。

vowels = {...}可以用dict.fromkeys('aeiou', 0)代替(请参阅dict.fromkeys

警告:仅当值不可变时才使用此功能。

>>> dict.fromkeys('aeiou', 0)
{'a': 0, 'i': 0, 'e': 0, 'u': 0, 'o': 0}




vowels = dict.fromkeys('aeiou', 0)

for t in text.lower():  # Change to lower once.
    if t in vowels:
        vowels[t] += 1

print vowels



或者,您也可以使用try ... except KeyError ...

for t in text.lower():  # Change to lower once.
    try:
        vowels[t] += 1
    except KeyError:  # Ignore consonants.
        pass


或使用附带的电池collections.Counter

from collections import Counter
vowels = Counter(c for c in text.lower() if c in 'aeiou')
# => Counter({'e': 54, 'a': 41, 'o': 40, 'i': 37, 'u': 14})


评论


\ $ \ begingroup \ $
天哪。这就是为什么我需要继续学习Python的原因。很简单。谢谢 :)
\ $ \ endgroup \ $
– nedlud
16年3月21日在7:27

\ $ \ begingroup \ $
值得注意的是,至少在2.x以及可能是某些较旧的3.x版本中,Counter效率低下。对于性能至关重要的代码,您需要使用dict版本(在某些情况下甚至可能是defaultdict版本)。
\ $ \ endgroup \ $
– jpmc26
16-3-21在11:40

\ $ \ begingroup \ $
+1,尽管同样值得一提的是EAFP版本(尝试:元音[t] + = 1,但KeyError:通过)。我怀疑在这种情况下并不理想,只是为了完整起见
\ $ \ endgroup \ $
– Tobias Kienzler
16-3-21在13:53

\ $ \ begingroup \ $
从可维护性的角度来看,用字符替换t以使其更容易快速地了解正在发生的事情不是更好吗?
\ $ \ endgroup \ $
– Cronax
16-3-21在14:22

\ $ \ begingroup \ $
您甚至不需要导入collections.Counter。然后,它是一个真正的衬里:元音= {v:'aeiou'中v的text.lower()。count(v)}
\ $ \ endgroup \ $
–西蒙·弗洛姆(Simon Fromme)
16年5月22日在21:41

#2 楼

另一个答案中概述的标准方法是:

vowels_2 = {'a':0, 'e':0, 'i':0, 'o':0, 'u':0}
for i in text.lower():
    if i in vowels_2:
        vowels_2[i] += 1

print vowels_2


,它转换为小写字母,然后递增字典中的元素。


另一种以更高效的方式使用Counter的方法:

from collections import Counter
data = Counter(text.lower())
vowels_3 = {i: data[i] for i in 'aeiou'}
print vowels_3


我认为这可能会更有效,因为我没有遍历的每个字符一个字符串,而是外包给性能库计算所有字符的计数器,然后仅选择我关心的计数。


以及使用另一种非常有用的字符串函数的另一种方式:翻译,将一组字符转换为另一组字符。在这里,我们基本上忽略了所有字符(请注意,您必须添加所有要忽略的字符,如果字符太多(例如unicode字符串),可能就不太好了。)

dict(Counter(text.lower().translate(None, 'bcdfghjklmnpqrstvxzwy 0123456789,.()')))