python之统计字符串中的字符个数

1.贴题

题目来自MOOC
《用Python玩转数据》(南京大学)
第三周编程作业


定义函数countchar()按字母表顺序统计字符串中所有出现的字母的个数(允许输入大写字符,并且计数时不区分大小写)。形如:

def countchar(str):
      ... ...
     return a list
if __name__ == "__main__":
     str = input()
     ... ...
     print(countchar(str))

输入格式:
字符串

输出格式:
列表

输入样例:
Hello, World!

输出样例:
[0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0]
时间限制:500ms内存限制:32000kb


2.说明

这道题确实费了一些功夫。
思路为以字母为key,出现次数为value建立字典,然后根据输入的字符串调用函数输出value值。(此处有一个坑,在后面说明)。

3.参考代码

def countchar(st): #定义数个数的函数
    keys = [chr(i+97) for i in range(26)] #生成26个字母的key列表
    di = {}.fromkeys(keys,0) #赋给每个key初始值0
    new = [] #建立一个新列表用于存放有序的key
    st = st.lower() #将所有输入的字符改为小写
    for s in st: #遍历字符串
        di[s] = st.count(s) #输出每个字符的个数,存放到字典里
    for k in di: #遍历字典
        if  k in keys: #如果key出现在26个字母中,则将其值添加到新列表,获得有序的26个字母的个数
            new.append(di[k])
    return new #返回存有26个字母个数的列表
if __name__ == "__main__":
    st = input() #输入字符串
    str1 = "" #定义一个空字符串
    for s in st: #遍历输入的字符串
        if s.isalpha() != 0: #只有字母才添加到新字符串,标点忽略不计
            str1 += s
    print(countchar(str1)) #输出列表

4.代码的注意点

  • 生成26个字母的代码一开始没想到要怎么写,直接手写的

    keys=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    

    然后遭到了吐槽。。

  • 命名dict的时候直接使用了dict,使用了python的保留字,虽然没有出错,但是还是遭到了无情的吐槽。。

  • 赋给每个元素初值的时候不记得具体怎么写了,查资料找到了通过fromkeys设置多个键的值
  • 巩固了将所有字符改为小写的写法 str.lower()
  • 实际使用了字符串的count函数 str.count(要数的字符或字符串)
  • 字典的key在字典里面的排序是无序的,因为没有注意到这一点,刚开始的代码是错的,因为输出来的列表顺序不对,请教了才修改正确的,增加了遍历然后添加到新列表的代码
  • 无视标点既可以创建一个含有各种特殊字符的字符串然后使用remove函数,如果只要求计数字母(或者只计数字)的时候,就可以使用专门的isalpha或者isdigit函数。相关资料Python isalpha()方法
  • 还有就是被吐槽使用count函数然后又有遍历循环的话会让程序的执行很慢。。

5.更好的代码

参考了以下几篇人家的博客

把代码修改为如下

def countchar(str):  
    alist = []  
    for i in range(26):     #初始化一个长度为26,值均为0的列表  
        alist.append(0)  
    str = str.lower()  
    for i in str:  #遍历字符串,如果是字母,则利用ascii码值转换为数字再平移至0-26范围内,将对应的列表值加一
        if i.isalpha():      
            alist[ord(i)-97] += 1  
    return alist  

if __name__ == "__main__": #主函数部分与原代码相同
    st = input()
    str1 = ""
    for s in st:
        if s.isalpha() != 0:
            str1 += s
    print(countchar(str1))

6.代码执行速度

在要统计的字符串为

st = "".join([chr(i+96)*i*100 for i in range(1,27)])

时,3的代码和5的代码的执行速度结果如下

3代码

[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600]
time: 1.108361 s

5代码

[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600]
time: 0.023698 s

确实速度相差50倍多啊。。

附3代码测试代码

import time
def countchar(st):
    keys = [chr(i+97) for i in range(26)]
    di = {}.fromkeys(keys,0)
    new = []
    st = st.lower()
    for s in st:
        di[s] = st.count(s)
    for k in di:
        if  k in keys:
            new.append(di[k])
    return new
if __name__ == "__main__":
    st = "".join([chr(i+96)*i*100 for i in range(1,27)])
    str1 = ""
    start = time.clock()
    for s in st:
        if s.isalpha() != 0:
            str1 += s
    print(countchar(str1))
    end = time.clock()
    print("time: %f s" % (end - start))

7.最后存档错误代码

下面的代码是不正确的!!!
错误原因(没有考虑到字典内部存储的时候是无序的)

def countchar(st):
    keys = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    dict = {}.fromkeys(keys,0)
    st = st.lower()
    for s in st:
        dict[s] = st.count(s)
    return list(dict.values())
if __name__ == "__main__":
    st = input()
    str1 = ""
    for s in st:
        if s.isalpha() != 0:
            str1 += s
    print(countchar(str1))

猜你喜欢

转载自blog.csdn.net/weixin_41980474/article/details/80048946