Chciałbym przechowywać dużo słów na liście. Wiele z tych słów jest bardzo podobnych. Na przykład mam słowa afrykanerskojęzyczny
i wiele słów, jak afrykanerskojęzycznym
, afrykanerskojęzyczni
, nieafrykanerskojęzyczni
. Jakie jest skuteczne (szybkie i dające mały rozmiar różnic) rozwiązanie, aby znaleźć różnicę między dwoma łańcuchami i przywrócić drugi ciąg z pierwszego i diff?
python
string
python-3.x
diff
user2626682
źródło
źródło
difflib
? Jeśli tak, zobacz, np stackoverflow.com/questions/774316/...Odpowiedzi:
Aby to zrobić, możesz użyć ndiff w module difflib. Zawiera wszystkie informacje niezbędne do konwersji jednego ciągu na inny.
Prosty przykład:
import difflib cases=[('afrykanerskojęzyczny', 'afrykanerskojęzycznym'), ('afrykanerskojęzyczni', 'nieafrykanerskojęzyczni'), ('afrykanerskojęzycznym', 'afrykanerskojęzyczny'), ('nieafrykanerskojęzyczni', 'afrykanerskojęzyczni'), ('nieafrynerskojęzyczni', 'afrykanerskojzyczni'), ('abcdefg','xac')] for a,b in cases: print('{} => {}'.format(a,b)) for i,s in enumerate(difflib.ndiff(a, b)): if s[0]==' ': continue elif s[0]=='-': print(u'Delete "{}" from position {}'.format(s[-1],i)) elif s[0]=='+': print(u'Add "{}" to position {}'.format(s[-1],i)) print()
wydruki:
afrykanerskojęzyczny => afrykanerskojęzycznym Add "m" to position 20 afrykanerskojęzyczni => nieafrykanerskojęzyczni Add "n" to position 0 Add "i" to position 1 Add "e" to position 2 afrykanerskojęzycznym => afrykanerskojęzyczny Delete "m" from position 20 nieafrykanerskojęzyczni => afrykanerskojęzyczni Delete "n" from position 0 Delete "i" from position 1 Delete "e" from position 2 nieafrynerskojęzyczni => afrykanerskojzyczni Delete "n" from position 0 Delete "i" from position 1 Delete "e" from position 2 Add "k" to position 7 Add "a" to position 8 Delete "ę" from position 16 abcdefg => xac Add "x" to position 0 Delete "b" from position 2 Delete "d" from position 4 Delete "e" from position 5 Delete "f" from position 6 Delete "g" from position 7
źródło
ndiff
jest generatorem, więc jest dość wydajny w pamięci. Wołaszlist
go, który zamienia indywidualnie wygenerowane porównania postaci w pełną ich listę. Gdybyś go nie wzywał, miałbyś w pamięci tylko kilka na razlist
.Podoba mi się odpowiedź ndiff, ale jeśli chcesz wypluć to wszystko na listę samych zmian, możesz zrobić coś takiego:
import difflib case_a = 'afrykbnerskojęzyczny' case_b = 'afrykanerskojęzycznym' output_list = [li for li in difflib.ndiff(case_a, case_b) if li[0] != ' ']
źródło
output_list = [li for li in list(difflib.ndiff(case_a,case_b)) if li[0] != ' ']
lub 2) Zmień nazwy zmiennych łańcuchowych nacase_a -> a
icase_b -> b
. Twoje zdrowie!>>> output_list
:; # wynik #['- b', '+ a', '+ m']
if not li.startswith(' ')
jest odpowiednikiem dlaif li[0] != ' '
Niektórzy mogą uznać to za bardziej czytelne. Lub nawetif item.startswith(('-', '+', ))
startswith()
stanu od Pythona3.7.4
Możesz zajrzeć do modułu regex (sekcja rozmyta). Nie wiem, czy możesz uzyskać rzeczywiste różnice, ale przynajmniej możesz określić dozwoloną liczbę różnych typów zmian, takich jak wstawianie, usuwanie i zastępowanie:
import regex sequence = 'afrykanerskojezyczny' queries = [ 'afrykanerskojezycznym', 'afrykanerskojezyczni', 'nieafrykanerskojezyczni' ] for q in queries: m = regex.search(r'(%s){e<=2}'%q, sequence) print 'match' if m else 'nomatch'
źródło
To, o co prosisz, to wyspecjalizowana forma kompresji. xdelta3 została zaprojektowana dla tego konkretnego rodzaju kompresji i jest do niej przypisana python, ale prawdopodobnie możesz uciec bezpośrednio używając zlib. Którą chcesz użyć
zlib.compressobj
izlib.decompressobj
zzdict
zestawu parametrów do „słowa bazowego”, npafrykanerskojęzyczny
.Ostrzeżenia są
zdict
obsługiwane tylko w Pythonie 3.3 i nowszych, a najłatwiej jest kodować, jeśli masz to samo „słowo bazowe” dla wszystkich różnic, co może być tym, czego chcesz lub nie.źródło
Odpowiedź na mój komentarz powyżej do Pierwotnego pytania sprawia, że myślę, że tylko tego chce:
loopnum = 0 word = 'afrykanerskojęzyczny' wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni'] for i in wordlist: wordlist[loopnum] = word loopnum += 1
Spowoduje to wykonanie następujących czynności:
Dla każdej wartości w liście słów, ustaw tę wartość listy słów na kod źródłowy.
Wszystko, co musisz zrobić, to umieścić ten fragment kodu w miejscu, w którym chcesz zmienić listę słów, upewniając się, że przechowujesz słowa, które chcesz zmienić w liście słów, i że oryginalne słowo jest poprawne.
Mam nadzieję że to pomoże!
źródło