Sortowanie wyników po zliczeniu liczby wystąpień.

0

Witam.

from timeit import default_timer as timer

start = timer()

input_file = open("slowa.txt", 'r')
file_contents = input_file.read()
input_file.close()
uniques = []
word_list = file_contents.split() #tworzy listę słów
for word in word_list:
            if word not in uniques:
                        uniques.append(word)
for word in uniques:
            print(word, " - ", word_list.count(word))
            
end = timer()

print('\n', "Czas wykonania: ", round(end - start, 2), "s")

Mam taki program, który to zlicza liczbę wystąpień każdego słowa w pliku tekstowym.
Potrzebuję posortować wyniki według liczby wystąpień, od największej do najmniejszej.

Jak mam to zrobić?

0

Na marginesie:
Zamiast:

input_file = open("slowa.txt", 'r')

zaleca się:

with open("slowa.txt", 'r') as input_file:
    operacje na pliku

A co do problemu:
https://stackoverflow.com/questions/23429426/sorting-a-list-by-frequency-of-occurrence-in-a-list

Ewentualnie:
Użyj słownika (dictionary) {słowo: liczba_wystąpień} i posortuj listę wedle wartości - https://stackoverflow.com/questions/72899/how-do-i-sort-a-list-of-dictionaries-by-a-value-of-the-dictionary-in-python

0

Kombinuję na różne sposoby i nie potrafię tego zrobić.
Aktualnie mam coś takiego:

for word in uniques:
            wyst = word_list.count(word)
            {word: wyst}
            newlist = sorted(wyst, key=lambda k: k[word]) 
            print(word, " - ", wyst)

i w efekcie dostaję komunikat:

Traceback (most recent call last):
  File "f:/Projekt/slowa.py", line 17, in <module>
    newlist = sorted(wyst, key=lambda k: k[word])
builtins.TypeError: 'int' object is not iterable
0
newlist = sorted(wyst, key=lambda k: k[word])

Sortujesz listę czy jej element?

W ogóle bym te uniques skasował

from collections import defaultdict

word_count = defaultdict(lambda: 0) #domyślnie każde słowo występuje 0 razy

for word in word_list:
    word_count[word] = word_list.count(word)

Jeśli potrzebujesz z defauldicta zrobić zwykłego, to można tak - new_dict = dict(defaultdict).

0
for word in uniques:
            wyst = word_list.count(word)
            lista = {word: wyst}
            newlist = sorted(lista, key=lambda k: k[wyst])
            print(newlist)

Mam tak, ale chyba nadal coś jest źle, bo listę wyświetla, ale nieposortowaną.

0
lista = {word: wyst}
 newlist = sorted(lista, key=lambda k: k[wyst])

Nie wiedziałem, że słownik da się sortować, ale wszystko przede mną.

I naprawdę - te uniques są tam do niczego niepotrzebne. Jak chcesz z użyciem słownika, to wyżej masz przykład. Możesz bez defauldict, ale nie jest to zbyt dobra praktyka (wówczas nie ma importu, lecz word_count = {}, a reszta jak dalej. Nie mówiąc, że z Counterem było by chyba najprościej.

PS. Jak chcesz się pozbyć duplikatów z listy:

lista = list(dict.fromkeys(lista))
0
for word in uniques:
            wyst = word_list.count(word)
            lista = [word, wyst]
            newlist = sorted(lista, key=lambda k: k[wyst])
            print(newlist)
builtins.TypeError: 'int' object is not subscriptable

Już się pogubiłem w tym wszystkim. Mógłbyś napisać jak powinien wyglądać ten fragment kodu? Potrzebuję po prostu szybko to skończyć, najlepiej na wczoraj :)

0

Wersja z Counterem (+/-):

from timeit import default_timer as timer
from collections import Counter

start = timer()
 
with  open("slowa.txt", 'r') as input_file:
    file_contents = input_file.read()
    word_list = file_contents.split() #tworzy listę słów
    new_list = sorted(word_list, key=Counter(word_list).get, reverse=True)  #sortowanie wedle wystąpień
    new_list = list(dict.fromkeys(new_list)) #eliminuje duplikaty
    print (new_list) # powinno wyświetlić listę wyrazów wedle występowania, bez powtórzeń
 
end = timer()
 
print('\n', "Czas wykonania: ", round(end - start, 2), "s")

Edit:
Gdybyś potrzebował wersji ze słownikiem:

with  open("slowa.txt", 'r') as input_file:
    file_contents = input_file.read()
    word_list = file_contents.split() #tworzy listę słów
    word_count = {word : word_list.count(word) for word in word_list} #się to zwie "dictionary comprehension"

Następnie sortujesz listę i eliminujesz duplikaty, jeśli to konieczne.

PS. Tak właściwie tej new_list mogłoby tam nie być.

0
Serechiel napisał(a):

Wersja z Counterem (+/-):

from timeit import default_timer as timer
from collections import Counter

start = timer()
 
with  open("slowa.txt", 'r') as input_file:
    file_contents = input_file.read()
    word_list = file_contents.split() #tworzy listę słów
    new_list = sorted(word_list, key=Counter(word_list).get, reverse=True)  #sortowanie wedle wystąpień
    new_list = list(dict.fromkeys(new_list)) #eliminuje duplikaty
    print (new_list) # powinno wyświetlić listę wyrazów wedle występowania, bez powtórzeń
 
end = timer()
 
print('\n', "Czas wykonania: ", round(end - start, 2), "s")

Czy w tym przypadku da się wyświetlić tą listę wraz z ilością powtórzeń danego słowa? I najlepiej jeszcze pionowo.

0
Squbany napisał(a):
Serechiel napisał(a):

Wersja z Counterem (+/-):

from timeit import default_timer as timer
from collections import Counter

start = timer()
 
with  open("slowa.txt", 'r') as input_file:
    file_contents = input_file.read()
    word_list = file_contents.split() #tworzy listę słów
    new_list = sorted(word_list, key=Counter(word_list).get, reverse=True)  #sortowanie wedle wystąpień
    new_list = list(dict.fromkeys(new_list)) #eliminuje duplikaty
    print (new_list) # powinno wyświetlić listę wyrazów wedle występowania, bez powtórzeń
 
end = timer()
 
print('\n', "Czas wykonania: ", round(end - start, 2), "s")

Czy w tym przypadku da się wyświetlić tą listę wraz z ilością powtórzeń danego słowa?

@Serechiel wszystko podał wraz z linkiem do stackoverflow z sortowaniem.W tym zadaniu na końcu dostaniesz słownik typu {'word': 2, 'word2':5}. Dict nie mogą być posortowane ale a) możesz użyć OrderedDict b) stworzyć listę na podstawie dict i ją posortować.

from operator import itemgetter
with  open("slowa.txt", 'r') as input_file:
    file_contents = input_file.read()
    word_list = file_contents.split() #tworzy listę słów
    word_count = {word : word_list.count(word) for word in word_list} #się to zwie "dictionary comprehension"
    sorted_words = sorted(d.items(), key=itemgetter(1))
0

Czy w tym przypadku da się wyświetlić tą listę wraz z ilością powtórzeń danego słowa?

Chodzi Ci o coś w stylu:
słowo - x razy?
Możesz spróbować tak:

word_count = Counter(word_list) # sugeruję dać to przed dokonaniem zmian w liście, wtedy sortowana lista tworzy się tak:
new_list = sorted(word_list, key=word_count.get, reverse=True)  #sortowanie wedle wystąpień
new_list = list(dict.fromkeys(new_list)) #eliminuje duplikaty

...
for word in new_list:
    print (word, word_count[word])
0
text = 'To jest to przykładowy jest tekst to test test test test'
occurences = {}

for t in text.split():
    is_in_dict = occurences.get(t.lower(), None)
    occurences[t.lower()] = occurences[t.lower()] + 1 if is_in_dict else 1
    # To samo co linia wyżej tylko bardziej czytelne
    # if is_in_dict:
    #     occurences[t.lower()] += 1
    # else:
    #     occurences[t.lower()] = 1

print(sorted(occurences.items(), key=lambda o: o[1], reverse=True))

Wynikiem jest posortowana lista tupli:

[('test', 4), ('to', 3), ('jest', 2), ('przykładowy', 1), ('tekst', 1)]
0

Proponuję bardziej zgrabnie:

from collections import Counter
text = 'To jest to przykładowy jest tekst to test test test test'
print(Counter(text.lower().split()).most_common())

[('test', 4), ('to', 3), ('jest', 2), ('przykładowy', 1), ('tekst', 1)]

1 użytkowników online, w tym zalogowanych: 0, gości: 1