为什么这个字符计数程序没有修改列表?

2024-04-16 22:42:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个程序来计算每个字母在文本中出现的次数。 我想把它转换成一个图表,逐行打印出条形图。当倒计时达到出现的次数时,在字母上方慢慢添加空格。你知道吗

import string
n=input("Enter Text, I wish you luck:")
list1=[]            #Empty List
list2=list(" "*26)  #26 space list
for a in string.ascii_uppercase:#from a-z
    n1=n.count(a)               #counts letters
    list1.append(n1)            #appends numbers
    m=max(list1)                #finds most occuring letter
c=m+1
while c!=0:                 
    c=c-1
    if c==0:
        print(string.ascii_uppercase)
        break
    for x in list1:             #suppose to check every term in list1
        if x >c:                #x is greater than countdowner
            k=list1.index(x)    #find term number
            list2[k]="*"        #replace blank with "*"
        elif x==c:
            #if x is equal to countdowner
            k=list1.index(x)    #find term number
            list2[k]="*"        #replaces that term place in list2
    print(''.join(list2))          

该代码只接受大写字母,现在它只向倒计时列表一次添加一个字母。因此,当计数达到一个外观,并且3个字母出现一次时,它将只在其中一个字母的顶部打印一个*。你知道吗

示例输入:HELLO STACKOVERFLOW

           *              
    *      *              
*   *      *                            
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Tags: inforstringif字母ascii次数list
1条回答
网友
1楼 · 发布于 2024-04-16 22:42:30

问题是k=list1.index(x)只能在list1中找到第一个出现的x。所以你可以在这里放一个循环,使用扩展形式index()

list1.index(x, start, end)

它只查找位于范围(开始,结束)中的索引

循环必须包含一个try: ... except块来处理ValueError异常。你知道吗

但还有另一种方法。你知道吗

#! /usr/bin/env python

from string import ascii_uppercase

def bargraph(data):
    data = data.upper()
    print(data)
    print(''.join(sorted(list(data))))

    #Count number of occurences of each letter in data
    counts = [data.count(a) for a in ascii_uppercase]

    #A single row of the bar graph, initially full of spaces
    row = list(" " * 26)

    for c in range(max(counts), 0, -1):
        for k in range(26):
            if counts[k] == c:
                row[k] = "*"

        print(''.join(row))

    print(ascii_uppercase)

def main():
    #data = input("Enter Text, I wish you luck:")
    data = "This is a test string for the bar graph function"
    bargraph(data)


if __name__ == '__main__':
    main()

我的程序版本将字符串转换为大写,打印它,然后对它进行排序并再次打印,以便于检查条形打印部分是否正在执行它应该执行的操作。你知道吗

它使用列表理解来构建字符计数列表。通过使用列表理解来构造row,它可以变得更短。你知道吗

def bargraph(data):
    data = data.upper()
    print(data)
    print(''.join(sorted(list(data))))

    #Count number of occurences of each letter in data
    counts = [data.count(a) for a in ascii_uppercase]

    for c in range(max(counts), 0, -1):
        print(''.join(["*" if counts[k] >= c else " " for k in range(26)]))

    print(ascii_uppercase)

两种版本的输出:)

THIS IS A TEST STRING FOR THE BAR GRAPH FUNCTION
         AAABCEEFFGGHHHIIIINNNOOPRRRRSSSSTTTTTTU
                   *      
                   *      
        *        ***      
*      **    *   ***      
*   *****    **  ***      
*** *****    *** ****     
ABCDEFGHIJKLMNOPQRSTUVWXYZ

编辑

我应该提到有一种更有效的方法来计算每个字母的出现次数。当前方法必须扫描数据字符串26次,每个字母扫描一次。这有点低效,尤其是当有很多数据要处理的时候。所以最好只扫描一次数据,然后累积计数。一种方法是使用dict

#! /usr/bin/env python

from string import ascii_uppercase

def bargraph(data):
    data = data.upper()
    print(data)
    print(''.join(sorted(list(data))))

    #Count number of occurences of each letter in data
    counts = dict(zip(ascii_uppercase, 26*(0,)))
    for c in data:
        if c.isupper():
            counts[c] += 1
    highcount = max(counts.values())

    for c in range(highcount, 0, -1):
        print(''.join([" *"[counts[k] >= c] for k in ascii_uppercase]))

    print(ascii_uppercase)

def main():
    #data = input("Enter Text, I wish you luck:")
    data = "This is a test string for the bar graph function"
    bargraph(data)


if __name__ == '__main__':
    main()

我还使用了一个小技巧,使行打印步骤更加紧凑。你知道吗

counts[k] >= c将是FalseTrue。你知道吗

但是Python允许我们像使用int值一样使用布尔值,其中False==0和True==1。你知道吗

因此,如果counts[k] >= cFalse,则" *"[counts[k] >= c]产生" ",如果True,则"*"。你知道吗

相关问题 更多 >