【问题标题】:counting letters in a string python计算字符串中的字母python
【发布时间】:2014-07-17 14:47:22
【问题描述】:

我必须编写一个函数countLetters(word),它将一个单词作为参数并返回一个列表,该列表计算每个字母出现的次数。字母必须按字母顺序排序。

这是我的尝试:

def countLetters(word):
    x = 0
    y = []
    for i in word:
        for j in range(len(y)):
            if i not in y[j]:
                x = (i, word.count(i))
                y.append(x)
    return y

我第一次尝试没有if i not in y[j]

countLetters("google")

结果是

[('g', 2), ('o', 2), ('o', 2), ('g', 2), ('l', 1), ('e', 1)] 

当我想要的时候

[('e', 1), ('g', 2), ('l', 1), ('o', 2)]

当我添加 if i not in y[j] 过滤器时,它只返回一个空列表 []。

有人可以在这里指出我的错误吗?

【问题讨论】:

    标签: python list dictionary count counter


    【解决方案1】:

    如果您使用的是 Python 2.7+,我推荐 collections 模块的 Counter

    >>> import collections
    >>> s = 'a word and another word'
    >>> c = collections.Counter(s)
    >>> c
    Counter({' ': 4, 'a': 3, 'd': 3, 'o': 3, 'r': 3, 'n': 2, 'w': 2, 'e': 1, 'h': 1, 't': 1})
    

    你可以在任何版本的 Python 中做同样的事情,只需要一两行:

    >>> c = {}
    >>> for i in s: 
    ...     c[i] = c.get(i, 0) + 1
    

    这对于检查您的工作也很有用。

    按字母顺序排序(以上按频率排序)

    >>> for letter, count in sorted(c.items()):
    ...     print '{letter}: {count}'.format(letter=letter, count=count)
    ... 
     : 4
    a: 3
    d: 3
    e: 1
    h: 1
    n: 2
    o: 3
    r: 3
    t: 1
    w: 2
    

    或者保持一种可以作为字典重复使用的格式:

    >>> import pprint
    >>> pprint.pprint(dict(c))
    {' ': 4,
     'a': 3,
     'd': 3,
     'e': 1,
     'h': 1,
     'n': 2,
     'o': 3,
     'r': 3,
     't': 1,
     'w': 2}
    

    最后,将其作为一个列表:

    >>> pprint.pprint(sorted(c.items()))
    [(' ', 4),
     ('a', 3),
     ('d', 3),
     ('e', 1),
     ('h', 1),
     ('n', 2),
     ('o', 3),
     ('r', 3),
     ('t', 1),
     ('w', 2)]
    

    【讨论】:

    • 最pythonic的方式。如果你想在你的问题中定义一个封闭的字母,你可以在 Counter 之前使用一个过滤器函数
    • 最好使用 Counter.most_common。排序是隐藏的,可以只得到 n most_common 并且很容易对其进行迭代。
    • 是的,但提问者要求它:“字母必须按字母顺序排序。”
    • 哦,好吧,我没看到这部分。所以必须更严格地定义字母表:在计数器之前过滤;排序中的关键函数以避免奇怪的结果(重音字符在哪里?);如果使用了奇怪的字母表(例如 UTF-8),则进行其他操作。
    【解决方案2】:

    我认为问题在于您的外部 for 循环,因为您正在迭代单词中的每个字母。

    如果单词包含多个特定字母,例如"bees",当它迭代它时,它现在将计算'e's 的数量两倍,因为for 循环不区分唯一价值观。查看字符串迭代器,这可能会更清楚地说明这一点。我不确定这是否能解决您的问题,但这是我注意到的第一件事。

    你可以试试这样的:

    tally= {}
    for s in check_string:
      if tally.has_key(s):
        tally[s] += 1
      else:
        tally[s] = 1
    

    然后您就可以从该字典中检索每个字母的计数。

    【讨论】:

      【解决方案3】:

      您的列表y 始终为空。你永远不会进入循环for j in range(len(y))

      附:你的代码不是很pythonic

      【讨论】:

        【解决方案4】:

        适用于最新的 Py3 和 Py2

        def countItems(iter):
          from collections import Counter
          return sorted(Counter(iter).items())
        

        【讨论】:

          【解决方案5】:

          使用字典并从@Aaron Hall的答案中打印出来

          import pprint
          def countLetters(word):
              y = {}
              for i in word:
              if i in y:
                  y[i] += 1
              else:
                  y[i] = 1
              return y
          
          res1 = countLetters("google")
          pprint.pprint(res1)
          
          res2 = countLetters("Google")
          pprint.pprint(res2)
          

          输出:

          {'e': 1, 'g': 2, 'l': 1, 'o': 2}

          {'G': 1, 'e': 1, 'g': 1, 'l': 1, 'o': 2}

          【讨论】:

            【解决方案6】:

            我不确定您的预期输出是什么,根据问题陈述,您似乎应该先对单词进行排序以按排序顺序获取字母数。下面的代码可能会有所帮助:

            def countLetters(word):
                letter = []
                cnt = []
                for c in sorted(word):
                    if c not in letter:
                        letter.append(c)
                        cnt.append(1)
                    else:
                        cnt[-1] += 1
                return zip(letter, cnt)
            
            print countLetters('hello')
            

            这会给你 [('e', 1), ('h', 1), ('l', 2), ('o', 1)]

            【讨论】:

            • 复杂度不好。如果您对输入进行排序,则复杂度取决于输入长度。如果按字母表排序,复杂度取决于字母表长度(通常小于输入)
            • 复杂度主要在于对单词进行排序,即O(NlogN)。那么你只需要对单词进行一次迭代就可以得到结果,不管字母长度如何,因为它总是在末尾追加或修改,也就是 O(N)。如果你使用字典,你只需要 O(N) 来设置 letter:cnt 映射,这很好,但如果你需要 sorted letter:cnt 对,你仍然需要对它进行排序,也就是 O(N i>logN),所以复杂度是一样的,这是我的看法。
            • N 是要排序的集合的长度。在第一种情况下,N = 长度(句子)。在第二种情况下,N = 长度(字母)。字母表通常很短且有限。一个句子的长度可能 = 5 或长度 = 5000000。所以复杂度不一样
            • 是的,你完全正确,虽然它们都是 O(N*logN),但可能会有很大的不同。谢谢。
            猜你喜欢
            • 2012-01-11
            • 2015-12-01
            • 2016-01-01
            • 2021-12-31
            • 1970-01-01
            • 1970-01-01
            • 2013-08-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多