2017-01-08 7 views
6

Как видно из названия говорит:Я пытаюсь посчитать все буквы в текстовом файле, то отображаются в порядке убывания

До сих пор это где я в моем коде работает, однако у меня возникли проблемы с отображением информации в порядке. В настоящее время он просто отображает информацию случайным образом.

def frequencies(filename): 
    infile=open(filename, 'r') 
    wordcount={} 
    content = infile.read() 
    infile.close() 
    counter = {} 
    invalid = "‘'`,.?!:;-_\n—' '" 

    for word in content: 
     word = content.lower() 
     for letter in word: 
      if letter not in invalid: 
       if letter not in counter: 
        counter[letter] = content.count(letter) 
        print('{:8} appears {} times.'.format(letter, counter[letter])) 

Любая помощь была бы принята с благодарностью.

ответ

1

Отображение в порядке убывания должно находиться за пределами вашей петли поиска, иначе они будут отображаться в том виде, в котором они встречаются.

Сортировка в порядке убывания довольно легко с помощью встроенного в sorted (вам необходимо установить reverse -argument!)

Однако питон батареи в комплекте и есть уже Counter. Так что это может быть так просто, как:

from collections import Counter 
from operator import itemgetter 

def frequencies(filename): 
    # Sets are especially optimized for fast lookups so this will be 
    # a perfect fit for the invalid characters. 
    invalid = set("‘'`,.?!:;-_\n—' '") 

    # Using open in a with block makes sure the file is closed afterwards. 
    with open(filename, 'r') as infile: 
     # The "char for char ...." is a conditional generator expression 
     # that feeds all characters to the counter that are not invalid. 
     counter = Counter(char for char in infile.read().lower() if char not in invalid) 

    # If you want to display the values: 
    for char, charcount in sorted(counter.items(), key=itemgetter(1), reverse=True): 
     print(char, charcount) 

Счетчик уже имеет метод most_common, но вы хотите, чтобы отобразить все символы и рассчитывает, так что это не подходит в данном случае. Однако, если вы хотите узнать только x самых общих счетчиков, тогда это будет подходящим.

5

Словари - это неупорядоченные структуры данных. Также, если вы хотите подсчитать некоторые элементы в наборе данных, вам лучше использовать collections.Counter(), который более оптимизирован и питоничен для этой цели.

Тогда вы можете просто использовать Counter.most_common(N), чтобы распечатать большинство N общих предметов в объекте Counter.

Также относительно открытия файлов вы можете просто использовать оператор with, который автоматически закрывает файл в конце блока. И лучше не печатать конечный результат внутри вашей функции, вы можете сделать свою функцию генератором, уступив намеченные строки, а затем распечатав их, когда захотите.

from collections import Counter 

def frequencies(filename, top_n): 
    with open(filename) as infile: 
     content = infile.read() 
    invalid = "‘'`,.?!:;-_\n—' '" 
    counter = Counter(filter(lambda x: not invalid.__contains__(x), content)) 
    for letter, count in counter.most_common(top_n): 
     yield '{:8} appears {} times.'.format(letter, count) 

Затем использовать цикл, чтобы перебрать функции генератора:

for line in frequencies(filename, 100): 
    print(line) 
4

Вам не нужно перебирать «слова», а затем над буквами в них. Когда вы перебираете строку (например, content), у вас уже будут отдельные символы (длина 1 строка). Затем вы хотите подождать до окончания цикла подсчета перед показом вывода. После подсчета, вы можете вручную сортировать:

for letter, count in sorted(counter.items(), key=lambda x: x[1], reverse=True): 
    # do stuff 

Однако лучше использовать collections.Counter:

from collections import Counter 

content = filter(lambda x: x not in invalid, content) 
c = Counter(content) 
for letter, count in c.most_common(): # descending order of counts 
    print('{:8} appears {} times.'.format(letter, number)) 
# for letter, number in c.most_common(n): # limit to n most 
#  print('{:8} appears {} times.'.format(letter, count)) 
0

Вы можете отсортировать словарь на момент печати, с sorted способом:

lettercount = {} 
invalid = "‘'`,.?!:;-_\n—' '" 
infile = open('text.file') 
for c in infile.read().lower(): 
    if c not in invalid: 
     lettercount[c] = lettercount.setdefault(c,0) + 1 
for letter in sorted(lettercount): 
    print("{} appears {} times".format(letter,lettercount[letter])) 

Rmq: я использовал метод изменения setdefault, чтобы установить значение по умолчанию 0, когда мы встречаем письмо в первый раз