Как видно из названия:

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

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]))

Любая помощь была бы очень признательна.

6
Andrew 8 Янв 2017 в 11:17

4 ответа

Лучший ответ

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

Сортировать по убыванию довольно просто, используя встроенный sorted (вам нужно установить аргумент reverse -!)

Однако python включает батареи , и уже есть 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 самых распространенных значений, это подойдет.

1
MSeifert 8 Янв 2017 в 16:34

Вы можете отсортировать свой словарь во время печати с помощью метода 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, когда мы встречаем букву в первый раз

0
Bertrand C. 8 Янв 2017 в 08:58

Вам не нужно перебирать слова, а затем буквы в них. Когда вы перебираете строку (например, 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))
4
schwobaseggl 8 Янв 2017 в 08:36

Словари являются неупорядоченными структурами данных. Также, если вы хотите подсчитать некоторые элементы в наборе данных, лучше использовать 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, чтобы перебрать функцию генератора:

for line in frequencies(filename, 100):
    print(line)
5
Kasramvd 8 Янв 2017 в 19:54