Я хотел бы сохранить в списке много слов. Многие из этих слов очень похожи. Например , у меня есть слово , afrykanerskojęzyczny
и многие из таких слов , как afrykanerskojęzycznym
, afrykanerskojęzyczni
, nieafrykanerskojęzyczni
. Каково эффективное (быстрое и дающее небольшой размер разницы) решение для поиска разницы между двумя строками и восстановления второй строки из первой и разницы?
python
string
python-3.x
diff
user2626682
источник
источник
difflib
? Если да, см., Например, stackoverflow.com/questions/774316/…Ответы:
Для этого вы можете использовать ndiff в модуле diffflib. В нем есть вся информация, необходимая для преобразования одной строки в другую.
Простой пример:
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()
печатает:
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
источник
ndiff
является генератором, поэтому он довольно эффективен с точки зрения памяти. Вы вызываетеlist
его, который превращает индивидуально сгенерированные сравнения персонажей в их полный список. Если бы вы не обращалисьlist
к нему, у вас было бы всего несколько в памяти одновременно .Мне нравится ответ ndiff, но если вы хотите выложить все это в список только изменений, вы можете сделать что-то вроде:
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] != ' ']
источник
output_list = [li for li in list(difflib.ndiff(case_a,case_b)) if li[0] != ' ']
либо 2) измените имена строковых переменных наcase_a -> a
иcase_b -> b
. Ура!>>> output_list
:; # результат #['- b', '+ a', '+ m']
if not li.startswith(' ')
является эквивалентомif li[0] != ' '
Некоторые могут найти его более разборчивым. Или дажеif item.startswith(('-', '+', ))
startswith()
питона3.7.4
Вы можете заглянуть в модуль регулярных выражений (нечеткий раздел). Я не знаю, сможете ли вы получить реальные различия, но, по крайней мере, вы можете указать допустимое количество различных типов изменений, таких как вставка, удаление и замены:
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'
источник
Вы просите об особой форме сжатия. xdelta3 был разработан для этого конкретного типа сжатия, и для него есть привязка к python, но вы, вероятно, можете обойтись без использования zlib напрямую. Вы хотели бы использовать
zlib.compressobj
иzlib.decompressobj
сzdict
параметром, установленным на ваше «базовое слово», напримерafrykanerskojęzyczny
.Предостережения
zdict
поддерживаются только в Python 3.3 и выше, и проще всего кодировать, если у вас есть одно и то же «базовое слово» для всех ваших различий, которое может быть или не быть тем, что вы хотите.источник
Ответ на мой комментарий выше по исходному вопросу заставляет меня думать, что это все, что он хочет:
loopnum = 0 word = 'afrykanerskojęzyczny' wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni'] for i in wordlist: wordlist[loopnum] = word loopnum += 1
Это сделает следующее:
Для каждого значения в списке слов установите для этого значения списка слов исходный код.
Все, что вам нужно сделать, это поместить этот фрагмент кода туда, где вам нужно изменить список слов, убедившись, что вы сохранили слова, которые нужно изменить, в списке слов, и что исходное слово правильное.
Надеюсь это поможет!
источник