Я хотел бы хранить много слов в списке. Многие из этих слов очень похожи. Например, у меня есть слово afrykanerskojęzyczny
и многие слова типа afrykanerskojęzycznym
, afrykanerskojęzyczni
, nieafrykanerskojęzyczni
. Какое эффективное (быстрое и дающее малый размер) решение, чтобы найти разницу между двумя строками и восстановить вторую строку из первой и diff?
Python - разница между двумя строками
Ответ 1
Вы можете использовать ndiff в модуле difflib для этого. Он имеет всю информацию, необходимую для преобразования одной строки в другую строку.
Простой пример:
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
Ответ 2
Вы можете заглянуть в модуль регулярных выражений (нечеткий раздел). Я не знаю, можете ли вы получить фактические различия, но по крайней мере вы можете указать допустимое количество различных типов изменений, таких как вставка, удаление и замены:
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'
Ответ 3
То, о чем вы просите, является специализированной формой сжатия. xdelta3 был разработан для этого конкретного вида сжатия, и для него существует привязка к python, но вы, вероятно, могли бы избежать использования zlib напрямую. Вы хотите использовать zlib.compressobj
и zlib.decompressobj
с параметром zdict
, установленным на ваше "базовое слово", например. afrykanerskojęzyczny
.
Предостережения zdict
поддерживаются только в python 3.3 и более поздних версиях, и проще всего закодировать, если у вас есть одно и то же "базовое слово" для всех ваших различий, которые могут быть или не быть тем, что вы хотите.
Ответ 4
Ответ на мой комментарий выше на оригинальный вопрос заставляет меня думать, что это все, что он хочет:
loopnum = 0
word = 'afrykanerskojęzyczny'
wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni']
for i in wordlist:
wordlist[loopnum] = word
loopnum += 1
Это сделает следующее:
Для каждого значения в списке слов установите это значение словарного списка в исходный код.
Все, что вам нужно сделать, это поместить этот фрагмент кода, где вам нужно изменить список слов, убедившись, что вы сохранили слова, которые нужно изменить в списке слов, и что исходное слово верное.
Надеюсь, это поможет!
Ответ 5
Мне нравится ответ ndiff, но если вы хотите переплести все это в список только изменений, вы можете сделать что-то вроде:
import difflib
case_a = 'afrykbnerskojęzyczny'
case_b = 'afrykanerskojęzycznym'
output_list = [li for li in list(difflib.ndiff(a,b)) if li[0] != ' ']