Python-两个字符串之间的差异

我想把很多单词存储在一个列表中。这些词中有许多是非常相似的。例如,我有单词 afrykanerskojęzyczny和许多像 afrykanerskojęzycznymafrykanerskojęzyczninieafrykanerskojęzyczni这样的单词。找出两个字符串之间的差异并从第一个字符串和差异恢复第二个字符串的有效解决方案是什么?

248115 次浏览

您可以查看 regex module(模糊部分)。我不知道您是否能够得到实际的差异,但至少您可以指定允许的不同类型的更改数量,如插入、删除和替换:

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'

对于我上面关于原始问题的评论,我的回答让我觉得这就是他想要的:

loopnum = 0
word = 'afrykanerskojęzyczny'
wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni']
for i in wordlist:
wordlist[loopnum] = word
loopnum += 1

这将做到以下几点:

For every value in wordlist, set that value of the wordlist to the origional code.

你所要做的就是把这段代码放在你需要改变单词表的地方,确保你把需要改变的单词存储在单词表中,并且原来的单词是正确的。

您可以在 afflib 模块中使用 恩迪夫来完成这项工作。它具有将一个字符串转换为另一个字符串所需的所有信息。

A simple example:

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

您所要求的是一种特殊形式的压缩。xdelta3是为这种特殊类型的压缩而设计的,并且有一个用于它的 Python 绑定,但是您可以直接使用 zlib。您可能希望使用 zlib.compressobjzlib.decompressobj,并将 zdict参数设置为“基本单词”,例如 afrykanerskojęzyczny

Caveats are zdict is only supported in python 3.3 and higher, and it's easiest to code if you have the same "base word" for all your diffs, which may or may not be what you want.

我喜欢这个 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] != ' ']

您可能会发现 < em > NLTK 图书馆中提供的工具对于计算不同单词之间的差异非常有用。

nltk.metrics.distance.edit_distance()是计算 莱文斯坦距离的成熟(非标准)库实现

一个简单的例子可能是:

from nltk.metrics.distance import *


w1 = 'wordone'
w2 = 'wordtwo'
edit_distance(w1, w2)


Out: 3

额外的参数允许根据不同操作(替换/插入)和不同字符差异(例如键盘上较近字符的成本较低)的成本对输出进行加权。