【问题标题】:Return how many times each letter of the alphabet appears in a string返回字母表中每个字母在字符串中出现的次数
【发布时间】:2017-04-04 09:52:10
【问题描述】:

我写了一个函数来计算给定字符串中单个字母的出现次数:

def count_letters(string, letter):
'''returns the number of letters letter in a sentence string.'''

count = 0
for char in string:
    if char == letter:
        count += 1
return count

现在,我想找到一种方法以列表格式返回所有字母出现的次数(假设它们都是小写字母 - 我使用的是string.lower())。我将一个字母计数器初始化为 26 个 0 的列表:

letter_counter = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

但我不确定如何遍历给定的字符串并为每个单独的字母附加列表。

例如。如果string = "Hello", letter_counter 返回:

letter_counter = [0,0,0,0,1,0,0,1,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0]

我认为这只是 for 循环中的 for 循环的问题,但它似乎更复杂。或者我只是看了太久了。

提前致谢。

【问题讨论】:

  • 使用collections.Counter 是最惯用的方法来计算序列中的出现次数。您还可以对 letter_counter 执行 for 循环,确保将每个索引转换为带有 chr(ord('A' + i)) 的字符。

标签: python string python-3.x iteration


【解决方案1】:
  • 这是一种计算每个字符出现频率的简单方法 字符串使用java编程
  • 注意:它按字母顺序而不是按顺序给出输出 发生。
  • 例如:输入:“Hello” 输出:e= 1 h= 1 l= 2 o= 1

    class char_frequency
        { public static void main (String s)
    { s=s.toLowerCase();
        for (char i= 'a'; i<='z'; i++)
        {check (s,i);}
    }
    
    public static void check (String s, char ch)
    { int l= s.length(); char a='a'; int c=0;
        for (int i= 0; i<=l-1; i++)
        { a= s.charAt (i);
            if (ch== a)
                c++;
    
        }
             if (c>0)
             System.out.println ( ch+ "= " + c);
    }
    

    }

【讨论】:

    【解决方案2】:

    要计算字母,您有多种选择,按优先顺序排列:

    1. collections.Counter 如果您想快速完成这项工作。
    2. 使用字典(Counter 就是这样做的)
    3. 使用(零)填充列表 - 您的方法。

    collection.Counter 方法非常简单:

    >>> from collections import Counter
    >>> Counter('hello').most_common()
    [('l', 2), ('h', 1), ('e', 1), ('o', 1)]
    

    字典方法需要更多的工作。有两种方法可以做到。第一种是使用字典的setdefault 方法来确保第一次看到一个字母时,它被正确初始化为默认值。

    >>> d = {}
    >>> for letter in 'hello':
    ...    d[letter] = d.setdefault(letter, 0) + 1
    ...
    >>> d
    {'h': 1, 'e': 1, 'l': 2, 'o': 1}
    

    第二种方法使用与上述相同的概念,但使用 defaultdict 代替:

    >>> from collections import defaultdict
    >>> d = defaultdict(int)
    >>> for letter in 'hello':
    ...    d[letter] += 1
    ...
    >>> d
    defaultdict(<type 'int'>, {'h': 1, 'e': 1, 'l': 2, 'o': 1})
    

    defaultdict 是一个带有可调用对象(一个函数)的对象,如果字典中不存在键,则该对象的值将被分配为默认值。与setdefault 相同,但功能更灵活。

    最后一个选项是一个零填充列表:

    >>> counts = [0 for i in range(25)]
    >>> for letter in 'hello':
    ...     counts[ord(letter.lower()) % 97] += 1
    ...
    >>> counts
    [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>> counts[11]
    2
    

    这种方法存在一些问题;最大的一个是它只适用于某些单词,它不适用于诸如hello world之类的短语或连接的单词,或者带有标点符号:We've won!

    您始终可以围绕这些进行编程,但其他方法没有这些问题。

    【讨论】:

      【解决方案3】:

      您可以将小写字符直接转换为基于 0 的索引,方法是使用 ord() 将它们转换为它们的 unicode 索引并减去 97('a' = 97、'b' = 98 等):

      def count_letters(word):
          l_count = [0] * 26
          for c in word.lower():
              l_count[ord(c)-97] += 1
          return l_count
      
      > count_letters('aaabbc')
      [3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      

      您绝对应该避免循环遍历字符串 26 次来单独计算每个字母!

      【讨论】:

        【解决方案4】:

        更好的方法是使用 Alessandro Power 和 Pythonista 建议的集合。如果您不想使用那个黑匣子,那么您可以这样做。

            # Replace this with your string
            string = 'AbcdEfghiJ'
            # create dictionary to locate a position of each letter
            str_dict = {'a':0, 'b':1, 'c':2, 'd':3, 'e':4, 'f':5, 'g':6, 'h':7,
                'i':8, 'j':9, 'k':10, 'l':11, 'm':12, 'n':13, 'o':14,
                'p':15, 'q':16, 'r':17, 's':18, 't':19, 'u':20, 'v':21,
                'w':22, 'x':23, 'y':24, 'z':25}
            letter_counter = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
            # locate a position of char in letter_counter and add 1.
            for char in string:
                str_lower = char.lower()
                letter_counter[str_dict[str_lower]] += 1
        
            print letter_counter
        

        输出[1]: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0]

        【讨论】:

        • 非常感谢!你知道我怎么能用句子做这个吗?当我尝试用空格做一个句子时(例如“hello goodbye”),它返回 Key Error: ' ' I tried to use .strip() 和 .replace(),但这不起作用。
        • @maio123maio:您应该添加“if char!=' ':”以确保只计算字母而不是空格。然后代码将如下所示:
        • ....... for char in string: if char!=' ': # '!=' 表示'不等于' str_lower = char.lower() letter_counter[str_dict[ str_lower]] += 1 打印 letter_counter
        【解决方案5】:

        为什么要重新发明轮子?

        您可以只使用collections.Counter(string),它将返回一个字典,其中字符串中的所有字母作为键,频率作为所述键的值。

        【讨论】:

        • 啊,很公平,我主要是想看看它是否可以用 for 循环来完成 :)
        猜你喜欢
        • 1970-01-01
        • 2016-01-23
        • 1970-01-01
        • 2020-07-23
        • 2016-06-27
        • 1970-01-01
        • 1970-01-01
        • 2022-07-27
        • 1970-01-01
        相关资源
        最近更新 更多