【问题标题】:Counting how many times each vowel appears计算每个元音出现的次数
【发布时间】:2018-10-24 16:46:31
【问题描述】:

我编写了一个小程序来计算每个元音出现在列表中的次数,但它没有返回正确的计数,我不明白为什么:

vowels = ['a', 'e', 'i', 'o', 'u']
vowelCounts = [aCount, eCount, iCount, oCount, uCount] = (0,0,0,0,0)
wordlist = ['big', 'cats', 'like', 'really']

for word in wordlist:
    for letter in word:
        if letter == 'a':
            aCount += 1
        if letter == 'e':
            eCount += 1
        if letter == 'i':
            iCount += 1
        if letter == 'o':
            oCount += 1
        if letter == 'u':
            uCount += 1
for vowel, count in zip(vowels, vowelCounts):
    print('"{0}" occurs {1} times.'.format(vowel, count))

输出是

"a" occurs 0 times.
"e" occurs 0 times.
"i" occurs 0 times.
"o" occurs 0 times.
"u" occurs 0 times.

但是,如果我在 Python shell 中键入 aCount,它会得到 2,这是正确的,所以我的代码确实更新了 aCount 变量并正确存储了它。为什么不打印正确的输出?

【问题讨论】:

  • 您将vowelCounts 分配给一个零元组。它与变量没有任何关系,也没有办法做到这一点。你最好在循环之后分配给它。
  • 只需使用collections.counter
  • 谜题的一部分:考虑foo = bar = 0foobar 都等于零也就不足为奇了。在vowelCounts = [aCount, eCount, iCount, oCount, uCount] = (0,0,0,0,0)中,python使用pythons [sequence unpacking](docs.python.org/3/tutorial/…)规则将(0,0,0,0,0)分配给[aCount, eCount, iCount, oCount, uCount],同时还将(0,0,0,0,0)分配给vowelCounts。如果你打印vowelCounts,你会注意到它是一个元组而不是一个列表。
  • 文体点。不要以这种方式使用多重赋值:a = b = (1, 2, 3)。它非常不可读,并导致难以跟踪错误(如果您不知道在哪里查看),例如此处的错误。

标签: python python-3.x list for-loop


【解决方案1】:

问题出在这一行:

vowelCounts = [aCount, eCount, iCount, oCount, uCount] = (0,0,0,0,0)

如果您稍后开始增加 aCountvowelCounts 不会得到更新。

设置a = [b, c] = (0, 0) 等效于a = (0, 0)[b, c] = (0, 0)。后者相当于设置b = 0c = 0

重新排序你的逻辑如下,它将起作用:

aCount, eCount, iCount, oCount, uCount = (0,0,0,0,0)

for word in wordlist:
    for letter in word:
        # logic 

vowelCounts = [aCount, eCount, iCount, oCount, uCount]

for vowel, count in zip(vowels, vowelCounts):
    print('"{0}" occurs {1} times.'.format(vowel, count))

【讨论】:

    【解决方案2】:

    您还可以使用集合计数器(这是计算事物时自然而然的首选函数,它返回一个字典):

    from collections import Counter
    
    vowels = list('aeiou')
    wordlist = ['big', 'cats', 'like', 'really']
    
    lettersum = Counter(''.join(wordlist))
    
    print('\n'.join(['"{}" occurs {} time(s).'.format(i,lettersum.get(i,0)) for i in vowels]))
    

    返回:

    "a" occurs 2 time(s).
    "e" occurs 2 time(s).
    "i" occurs 2 time(s).
    "o" occurs 0 time(s).
    "u" occurs 0 time(s).
    

    字母:

    Counter({'l': 3, 'a': 2, 'e': 2, 'i': 2, 'c': 1, 'b': 1, 
             'g': 1, 'k': 1, 's': 1, 'r': 1, 't': 1, 'y': 1})
    

    【讨论】:

      【解决方案3】:

      您可以使用字典理解:

      vowels = ['a', 'e', 'i', 'o', 'u']
      wordlist = ['big', 'cats', 'like', 'really']
      new_words = ''.join(wordlist)
      new_counts = {i:sum(i == a for a in new_words) for i in vowels}
      

      输出:

      {'a': 2, 'e': 2, 'i': 2, 'o': 0, 'u': 0}
      

      【讨论】:

        【解决方案4】:

        除了@jpp 所说的 像整数这样的简单数据类型是按值而不是按引用返回的 因此,当您将其分配给某事物并更改该事物时,它不会受到影响

        a = 10
        b = a #b=a=10
        b = 11 #b=11, a=10
        print a, b
        --> 10 11
        

        我会对此发表评论,但我需要声誉才能做到这一点:D

        【讨论】:

        • 不完全。这里的区别是 b 正在被重新分配。尝试a = [10];b=a;b=[11]`,您会看到相同的行为,即使列表绝对不是“按值返回”。
        • 但是 b=[11] 正在将 b 重新分配给另一个列表,而如果您现在执行 b[0]=11 a=[11]
        • 你做了b = 11 这是重新分配。 python 对象的区别不在于它们是通过值传递还是通过引用传递(它们都以相同的方式传递),而是它们是可变的还是不可变的,或者更根本的是,它们的“魔术”方法做了什么。在b[0]=11 中,可变对象的list.__setitem__() 方法被调用,它决定了要做什么。没有重新分配 b 本身。
        • 似乎我的 c++ 背景再次让我受益匪浅,谢谢您的澄清
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多