2017-01-08 39 views
6

Jak sam tytuł mówi:Próbuję policzyć wszystkie litery w pliku txt następnie wyświetlić w malejącym porządku

Jak dotąd jest to, gdzie jestem w moim kodu działa jednak mam problem z wyświetlaniem informacji w celu. Obecnie po prostu wyświetla informacje losowo.

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

Każda pomoc zostanie bardzo doceniona.

Odpowiedz

1

Wyświetlanie w kolejności malejącej musi znajdować się poza twoją pętlą wyszukiwania, w przeciwnym razie będą wyświetlane tak, jak są napotkane.

Sortowanie w kolejności malejącej jest dość łatwe przy użyciu wbudowanego sorted (musisz ustawić reverse -argument!)

Jednak pyton jest baterie i istnieje już Counter. Więc może to być po prostu jak:

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) 

Licznik ma już metodę most_common ale chcesz wyświetlić wszystkie znaki i liczby więc nie jest dobrym rozwiązaniem w tym przypadku. Jednakże, jeśli chcesz tylko znać x najczęściej używanych liczb, to będzie to odpowiednie.

5

Słowniki są nieuporządkowanymi strukturami danych. Również jeśli chcesz policzyć niektóre elementy w zbiorze danych, lepiej użyć wartości collections.Counter(), która jest bardziej zoptymalizowana i pythonic do tego celu.

Następnie można po prostu użyć Counter.most_common(N), aby wydrukować większość popularnych przedmiotów z obiektu Counter.

Również w odniesieniu do otwierania plików, można po prostu użyć instrukcji with, która automatycznie zamyka plik na końcu bloku. Lepiej jest nie drukować końcowego wyniku wewnątrz funkcji, możesz sprawić, że twoja funkcja będzie generatorem, generując zamierzone linie, a następnie drukuje je, kiedy chcesz.

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) 

Następnie za pomocą pętli for w celu iteracyjnego funkcji generatora:

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

Nie trzeba iteracyjne nad „słowa”, a następnie w ciągu liter w nich. Podczas iteracji ciągu znaków (np. content), masz już pojedyncze znaki (długość 1 ciągi). Następnie, przed wyświetleniem danych wyjściowych, należy poczekać do zakończenia pętli liczenia. Po zliczeniu, można ręcznie sortowania:

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

Jednak lepsze wykorzystanie 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

można sortować słownika w momencie drukowania, metodą 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: Użyłem setdefault metody zmiany, aby ustawić domyślną wartość na 0, gdy spotykamy się z literą po raz pierwszy