2016-11-21 92 views
0

我写了一个函数来计算一个单个字母的出现给定的字符串:返回多少次出现在每个字母在字符串

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] 

但我不知道如何遍历一个给定的字符串和追加列表为每个字母。

Ex。如果,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循环的问题,但似乎更加复杂。或者我可能只是看了太久。

在此先感谢。

+0

使用'collections.Counter'是序列中出现次数最常用的方法。你也可以在'letter_counter'上做一个for循环,确保将每个索引转换成带有'chr(ord('A'+ i))'的字符。 –

回答

1

为什么重新发明轮子?

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

+0

啊,足够公平,我主要只是想看看它是否可以用循环:) – maio123maio

1

更好的方法是使用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]

+0

非常感谢!你知道我如何用句子做这个工作吗?当我尝试用空格(例如“hello goodbye”)做一个句子时,它会返回键错误:''我试图使用.strip()和.replace(),但那不起作用。 – maio123maio

+0

@ maio123maio:您应该添加“if char!='':”以确保只计算字母而不是空格。然后,代码将如下所示: –

+0

....... char:string中的字符: if char!='':#'!='意味着'不等于' str_lower = char.lower( ) letter_counter [str_dict [str_lower]] + = 1 print letter_counter –

0

您可以使用ord()将小写字符转换为基于0的索引并将其减去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次来单独计算每个字母!

1

要算字母,你有很多选择,按优先顺序:

  1. collections.Counter,如果你想获得这个快速完成。
  2. 使用字典(这是什么Counter做什么)
  3. 使用(零)填充列表 - 您的方法。

的collection.Counter做法很简单:

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

的字典方法,需要多做一些工作。有两种方法可以做到这一点。第一种方法是使用字典的方法来确保在第一次看到一封信时,它会使用默认值正确初始化。

>>> 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!

您可以围绕这些经常方案,但其他方法不要没有这些问题。

相关问题