我想在列表中存储很多单词。其中许多词非常相似。例如,我有单词afrykanerskojęzyczny
和许多单词,例如afrykanerskojęzycznym
, afrykanerskojęzyczni
, nieafrykanerskojęzyczni
。找到两个字符串之间的差异并从第一个字符串和 diff 恢复第二个字符串的有效(快速且差异大小)解决方案是什么?
6 回答
您可以在 difflib 模块中使用ndiff来执行此操作。它具有将一个字符串转换为另一个字符串所需的所有信息。
一个简单的例子:
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 的答案,但如果你想把它全部吐到一个只有更改的列表中,你可以这样做:
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] != ' ']
您可以查看正则表达式模块(模糊部分)。我不知道您是否可以获得实际差异,但至少您可以指定允许的不同类型更改的数量,例如插入、删除和替换:
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
andzlib.decompressobj
将zdict
参数设置为您的“基本词”,例如afrykanerskojęzyczny
.
警告zdict
仅在 python 3.3 及更高版本中受支持,如果您的所有差异都有相同的“基本词”,则最容易编码,这可能是也可能不是您想要的。
您可能会发现NLTK库中可用的工具可用于计算不同单词之间的差异。
nltk.metrics.distance.edit_distance()
是计算Levenshtein 距离的成熟(非标准)库实现
一个简单的例子可能是:
from nltk.metrics.distance import *
w1 = 'wordone'
w2 = 'wordtwo'
edit_distance(w1, w2)
Out: 3
附加参数允许对输出进行加权,具体取决于不同操作(替换/插入)和不同字符差异的成本(例如,靠近键盘的字符成本更低)。
我上面对原始问题的评论的答案让我认为这就是他想要的:
loopnum = 0
word = 'afrykanerskojęzyczny'
wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni']
for i in wordlist:
wordlist[loopnum] = word
loopnum += 1
这将执行以下操作:
对于 wordlist 中的每个值,将 wordlist 的值设置为原始代码。
您所要做的就是将这段代码放在您需要更改单词表的地方,确保您将需要更改的单词存储在单词表中,并且原始单词是正确的。