2014-10-22 40 views
1

我正在写一个程序来计算每个字母出现在文本中的次数。 我试图通过逐行打印出条形图将其转换为图形。当倒计时达到出现次数时,慢慢地在字母上方添加空格。为什么这个字符计数器程序不能改变列表?

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计算器

  *    
    *  *    
* *  *        
ABCDEFGHIJKLMNOPQRSTUVWXYZ 

回答

2

的问题是,k=list1.index(x)只能找到list1x第一次出现。所以,你可以把一个循环这里,使用的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次,每个字母一次。这有点低效,尤其是在需要处理大量数据的情况下。所以最好只扫描一次数据,并累计计数。一种方法是使用字典。

#! /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] >= c]结果" "如果counts[k] >= cFalse,并"*"如果是True

+0

非常感谢! :d – 2014-10-22 18:52:33