Forum Coders' city Strona Główna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Potrzebuję szybkiej odpowiedzi na moje pytanie... Zasady

Bisect i polskie litery

Idź do strony 1, 2, 3, 4  Następny

 
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Python
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
mazur
Gość





PostWysłany: Czw Paź 13, 2016 8:41 pm  OP    Temat postu: Bisect i polskie litery Odpowiedz z cytatem Pisownia

Witam, mam następujący kod:

Kod:
#!python
# -*- coding: utf-8 -*-

import bisect
listaSlow= [u'ala', u'beata', u'danuta', u'łucja', u'nina', u'zygmunt']

slowo = u"ala" # wynik: 0 1
slowo = u"beata" # 1 2
slowo = u"celina" # 2 2
slowo = u"nina" # 3 3 (powinno być: 3 4)
slowo = u"marek" # 3 3
slowo = "łucja" # błąd: UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)
slowo = u"łucja" # 3 6
slowo = u"zygmunt" # 3 3 (powinno być: 5 6 lub 5 5)
slowo = u"świętopełk" # 6 6
slowo = u"nina"

print = bisect.bisect_left(listaSlow, slowo)
print = bisect.bisect(listaSlow, slowo)


W komentarzu wpisałem wynik działania.
Jak poprawić program, by działał ze znakami unicode?
Pozdrawiam
Robert
Powrót do góry
hurgadion



Dołączył: 06 Kwi 2011
Posty: 776
Skąd: Web :)

PostWysłany: Nie Paź 16, 2016 7:25 pm      Temat postu: Odpowiedz z cytatem Pisownia

Hej,
nie wgryzałem się za bardzo w Twój problem, ale znalazłem to... Co prawda, to jest japoński, ale idea powinna być podobna... Pzdr.

_________________
miasto nauki praktycznej
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Odwiedź stronę autora Numer GG
mazur
Gość





PostWysłany: Pon Paź 17, 2016 12:50 am  OP(?)    Temat postu: Odpowiedz z cytatem Pisownia

Niestety nie działa:

Kod:
J = [u"ala", u"beata", u"danuta", u"łucja", u"nina", u"zygmunt"]
print sorted(J)


otrzymuję:
[u'ala', u'beata', u'danuta', u'nina', u'zygmunt', u'\u0142ucja']

Pzdr
Robert
Powrót do góry
marcin_an



Dołączył: 26 Maj 2005
Posty: 18813

PostWysłany: Pon Paź 17, 2016 2:01 am      Temat postu: Odpowiedz z cytatem Pisownia

Do funkcji sorted zawsze* trzeba przekazać co najmniej dwie rzeczy**: sortowaną kolekcję oraz komparator. Podałeś komparator? Nie podałeś. Zatem wynik może być dowolny i nie powinieneś spodziewać się żadnego konkretnego uporządkowania.

Python ma o tyle specyficzną funkcję sorted, że nie przyjmuje ona komparatora wprost. Zamiast tego akceptuje funkcję, której zadaniem jest wyłuskanie klucza z każdego elementu. To ta funkcja powinna zwrócić taki obiekt, że będzie on dekorował właściwą wartość i definiował dla niej odpowiedni porządek (czyli będzie porównywalny z innymi takimi obiektami). Na szczęście nie trzeba tworzyć klasy od zera: dostępna jest funkcja cmp_to_key, która "konwertuje" komparator na argument dla sorted:
Kod:
import functools
import locale

locale.setlocale(locale.LC_ALL, '')
values = [u"ala", u"beata", u"zygmunt", u"nina", u"danuta", u"łucja"]
print(sorted(values, key=functools.cmp_to_key(locale.strcoll)))



____
* Jedynym wyjątkiem są wartości posiadające naturalny porządek: np. liczby. I to też nie wszystkie, i doatkowo pod warunkiem, że sortowanie ma być zgodne z naturalnym porządkiem. Biorąc pod uwagę, że gołe liczby sortuje się rzadko, możesz spokojnie przyjąć, że "zawsze" jest właściwym określeniem.
** Dotyczy to każdego języka programowania i/lub biblioteki, nie tylko Pythona. Jeżeli język lub biblioteka nie mają funkcji sortującej bez takiej własności, nie nadają się do praktycznego zastosowania.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
mazur
Gość





PostWysłany: Pon Paź 17, 2016 10:53 am  OP(?)    Temat postu: Odpowiedz z cytatem Pisownia

Dziękuje za odpowiedź, sprawa sortowania została poprawiona (choć listę mam już posortowaną).

Pozostaje jednak dla mnie problem najważniejszy:

Kod:
values = [u"ala", u"beata", u"danuta", u"łucja", u"nina", u"zygmunt"]
word = u"nina"
print bisect.bisect_left(J, word)


dlaczego dla
word = u"łucja" wynik jest 3
word = u"nina" wynik jest 3
word = u"zygmunt" wynik jest 3

Wygląda na to, że "ł" (czyli polskie litery) zaburza działanie "bisect".
Może dla "bisect" też trzeba jakoś zdefiniować kryterium sortowania, jak w przypadku "sorted"?

Pozdrawiam
Robert
Powrót do góry
marcin_an



Dołączył: 26 Maj 2005
Posty: 18813

PostWysłany: Pon Paź 17, 2016 11:32 am      Temat postu: Odpowiedz z cytatem Pisownia

Przy dowolnej operacji wymagającej porządku konieczne jest przekazanie czegoś, co definiuje ten porządek*. Rodzina bisect_... nie jest wyjątkiem. Niemniej pomimo zgłaszania błędu, twórcy Pythona co najmniej od 2005** odrzucają sprawę, więc cały ten moduł jest niezdatny do praktycznego użycia. Jeśli koniecznie chcesz go używać, masz dwie opcje. Obydwie wymagają napisania klasy, która owija porównywaną wartość i udostępnia dla niej odpowiedni porządek (patrz: total_ordering z modułu functools). Następnie są dwie opcje:
  1. Przed sortowaniem zrobić durgą listę, do której kopiuje się wszystkie elementy z pierwszej, owijając je we wspomnianą klasę.
  2. Zrobić własną listę, która trzyma referencję do oryginalnej listy, a przy dostępie do elementu udostępnia go w takiej owijce.
Być może nawet już ktoś to zaimplementował i możesz użyć gotowego rozwiązania, ale niestety w tej kwestii nic nie podpowiem - Pythona używam od wielkiego dzwonu, tylko podczas psucia/naprawiania/rozwijania kodu innych osób.

Ale zanim zaczniesz się męczyć i marnować na to czas, najważniejsze pytanie: po co to w ogóle robisz? W wątku, z którego zrodziło się to pytanie podane przecież zostały rozwiązania, które załatwiają ci to od ręki. Np. słownik. Dlaczego chcesz wynajdywać od nowa [kwadratowe] koło, skoro masz to już zrobione w samym języku? Dalej: czy te dane są na tyle duże, a liczba wyszukiwań na tyle znacząca, by w ogóle opłacało się pakować to do słownika? Sugerowałem przecież, że dla tak małych danych prawdopodobnie najlepszym rozwiązniem będzie znalezienie odpowiedniego ciągu bezpośrednio w danych z pliku - bez pakowania tego do jakichkolwiek struktur.

Na marginesie: jeśli sortowania potrzebujesz tylko do binsearcha, to nie ma znaczenia, czy otrzymana kolejność elementów ma jakikolwiek sens. Ważne jest tylko, żeby wszystkie zaangażowane w to funkcje używały tego samego porządku. sorted oraz bisect_... spełniają ten warunek. Jeśli sorted uzna, że wszystkie liczby parzyste mają być przed nieparzystymi i np. z listy [0, 1, 2, 3, 4, 5, 6, 7] zrobi [0, 2, 4, 6, 8, 1, 3, 5, 7], ale funkcje bisect_... też będą tak sądziły, to wszystko gra, jak długo tylko w obrębie takich tworów działasz. Wcześniej wskazałem na brak komparatora, bo twój problem dotyczył sensowności (z ludzkiego punktu widzenia) otrzymanego wyniku sortowania. Ale jeśli to nigdy nie ma trafić do człowieka, to nie ma problemu.
____
* Uwagi dot. innych języków oraz naturalnego porządku - analogiczne jak wcześniej.
** issue#1185383, powtarzane w różnych wersjach i z różnymi proponowanymi rozwiązaniami (język się zmienia) przez kolejne 11 lat.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
mazur
Gość





PostWysłany: Pon Paź 17, 2016 2:31 pm  OP(?)    Temat postu: Odpowiedz z cytatem Pisownia

Jeszcze raz bardzo dziękuję za wyczerpującą odpowiedź.

Nie jestem programistą zawodowym, więc moje umiejętności nie są bardzo duże.

Może powtórzę do czego mi jest potrzebny ten program.
Do wspomagania tłumaczenia:
1. Posiadam słownik w wersji djvu (skan).
2. Posiadam indeks słów z tego słownika, tj. słowo + nr strony (format txt)
3. Jednak w tym indeksie są tylko PIERWSZE słowa z każdej strony, a NIE WSZYSTKIE słowa słownika.
Czyli w indeksie (pkt.2) nie ma wszystkich słów, stąd nie mogę ich prosto wyszukiwać.
4. "bisect" zwraca miejsce słowa lub miejsce gdzie byłoby, gdyby było w indeksie (posortowanym).
Stąd tak bardzo uczepiłem się "bisect".

Chciałem znaleźć jakieś eleganckie rozwiązanie.

Niestety nie jestem w stanie napisać sobie tego "owijania".

Na razie poradziłem sobie w następujący sposób: wyszukuję słowa, jeśli go nie ma: obcinam ostatnią literę i przeszukuję, jeśli nie znaleziono słowa: odcinam kolejną literę od końca, aż do znalezienia najbardziej podobnego słowa. Następnie odczytuję nr strony i otwieram słownik na tej stronie.

Rekordów jest ok. 10 tys.

Pozdrowienia
Robert
Powrót do góry
hurgadion



Dołączył: 06 Kwi 2011
Posty: 776
Skąd: Web :)

PostWysłany: Pon Paź 17, 2016 4:13 pm      Temat postu: Odpowiedz z cytatem Pisownia

mi się wydaje, że przy takiej ilości rekordów nie ma się co zastanawiać, wystarczy to zrobić zwykłą pętlą, nawet chyba sprawdzając słowa znak po znaku, o ile to konieczne... przetestuj i jak coś nie pójdzie, to zamelduj się z wynikiem i z kolejnym problemem... będziemy myśleli dalej...
_________________
miasto nauki praktycznej
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość Odwiedź stronę autora Numer GG
mazur
Gość





PostWysłany: Pon Paź 17, 2016 9:12 pm  OP(?)    Temat postu: Odpowiedz z cytatem Pisownia

Dobrze, na razie bardzo dziękuję za pomoc.

Może tylko jedna uwaga:
mam monitor 13 cali, Win7, Firefox i trochę trudno czyta się to forum, ponieważ nie są zawijane wiersze przy powiększaniu liter. Aby przeczytać linię tekstu trzeba przesuwać suwak.

Pozdrowienia
Robert
Powrót do góry
marcin_an



Dołączył: 26 Maj 2005
Posty: 18813

PostWysłany: Pon Paź 17, 2016 9:23 pm      Temat postu: Odpowiedz z cytatem Pisownia

Dlatego że w pierwszym kodzie dałeś potwornie długą linijkę. Kody źródłowe z założenia nie są zawijane, więc rozciągają całą stronę. Przy przestrzeganiu standardowych 80 znaków na linię nic takiego by się nie stało.

Co do wyszukiwania: właśnie dlatego należy dokładnie przedstawić problem do rozwiązania, a nie założyć konkretne podejście i potem pytać, jak je zrobić. Odwróć swoje rozwiązanie. Zamiast odcinać ostatnie litery, zaczynaj od pierwszej i dodawaj kolejne, zaczynając wyszukiwanie od punktu, gdzie znaleziono ostatni pasujący ciąg. Przykładowo dla słownika:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko
niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące
nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję
... i szukania "nieprzyklepywać":
Krok 1: szukanie "n" od linii 1:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową

neodarwinistko
niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące
nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

Krok 2: szukanie "ni" od linii 14:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko

niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące
nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

Krok 3: szukanie "nie" od linii 15:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko

niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące
nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

Krok 4: szukanie "niep" od linii 15:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko
niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych

nieporzygujące
nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

Krok 5: szukanie "niepr" od linii 19:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko
niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące

nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

Krok 5: szukanie "nieprz" od linii 20:
akceptowałyby
Burgundami
diktiosomowi
dosuwowy
dusiciel
Eufemianom
itelmeńskich
kartuzom
kwikach
lamerach
leptosomy
megacerosów
młotową
neodarwinistko
niedwuśrubowym
nienapakowanych
nieodważonych
nieoglądanych
nieporzygujące

nieprzemilczanym
nieprzyklepującą
nietrzewiczkowej
niewartowaniom
niezawisakowatemu
ofrankujecie
papawerynie
przemagnesowałybyście
przymarzając
Siejakowskimi
syntetyzowanemu
trałowi
trzeźwemu
uzyskiwaniach
weksylologiczną
wielkooporowym
załaskotałeś
załogantka
zapłakałam
zaprzysięgalibyście
zarysuję

I tak dalej. W którymś momendzie będzie szukanie "nieprzyklepy", które nie znajdzie wyniku i będzie wiadomo, że ostatnio napotkana linia to ta, której szukasz. Nota bene: nie będzie tego również w słowniku, bo zrobiłem błąd gramatyczny - powinno być "nie przyklepywać", które oczywiście nie jest lemmą. Nie chce mi się już jednak drugi raz tworzyć całego przykładu ;).

Proponuję też zmienić format linii w pliku na "nr_strony lemma". Będzie trochę prostsze w użyciu.

10000 wpisów to bardzo mało, więc nie masz czym się przejmować - wczytaj do pamięci cały plik i wyszukaj w tekście, czego ci trzeba.
Powrót do góry
Zobacz profil autora Wyślij prywatną wiadomość
Wyświetl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Główna -> Python Wszystkie czasy w strefie CET (Europa)
Idź do strony 1, 2, 3, 4  Następny
Strona 1 z 4

 
Skocz do:  
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Możesz dodawać załączniki na tym forum
Możesz pobierać pliki z tego forum




Debug: strone wygenerowano w 0.03064 sekund, zapytan = 12
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |