【问题标题】:Python - difference between two stringsPython - 两个字符串之间的区别
【发布时间】:2013-07-28 01:35:03
【问题描述】:

我想在一个列表中存储很多单词。其中许多词非常相似。例如,我有单词afrykanerskojęzyczny 和许多单词,如afrykanerskojęzycznymafrykanerskojęzyczninieafrykanerskojęzyczni。找到两个字符串之间的差异并从第一个字符串和 diff 恢复第二个字符串的有效(快速且差异大小)解决方案是什么?

【问题讨论】:

  • “从第一个字符串恢复第二个字符串并进行比较”是什么意思?
  • 我相信他的意思是“使第二个字符串与第一个字符串相同”。
  • @EliasBenevedes,确切地说:)。
  • 您在寻找类似difflib 的东西吗?如果是这样,请参阅,例如,stackoverflow.com/questions/774316/…

标签: python string python-3.x diff


【解决方案1】:

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

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

这将执行以下操作:

对于 wordlist 中的每个值,将 wordlist 的值设置为原始代码。

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

【讨论】:

  • 谢谢,但实际上我想使用与 'afrykanerskojęzyczny' 的相似性,以一种内存有效的方式存储像 'nieafrykanerskojęzyczni' 这样的词。
【解决方案2】:

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

【讨论】:

  • 这正是我在谷歌上搜索的目的。一个快速说明,@Eric,您的变量与今天显示的 20180905 不匹配。要么 1) 将最后一行更改为 output_list = [li for li in list(difflib.ndiff(case_a,case_b)) if li[0] != ' '],要么 2) 将字符串变量的名称更改为 case_a -> acase_b -> b。干杯!
  • 显示命令的输出也可能会有所帮助:>>> output_list; #结果#['- b', '+ a', '+ m']
  • if not li.startswith(' ') 等同于if li[0] != ' ' 有些人可能会觉得它更易读。甚至if item.startswith(('-', '+', ))
  • @DMfll 否决票。列表没有 startswith() 从 python 3.7.4
  • @Nathan 您不能对 cme​​ts 投反对票,虽然您的列表没有开头是正确的,但您已经完全搞砸了类型。 li 是一个字符串,而不是一个列表,至少从 2012 年开始,字符串就有了 startswith()。字符串可以像数组一样被索引,因为字符串本质上是一个美化的 unsigned (w)char[],实际上是一个数组.尝试运行代码 - output_list = [li for li in difflib.ndiff(case_a, case_b) if not li.startswith(' ')] 在 3.9 上对我来说非常好
【解决方案3】:

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

注意事项是 zdict 仅在 python 3.3 及更高版本中受支持,如果您对所有差异都有相同的“基本词”,则最容易编码,这可能是也可能不是您想要的。

【讨论】:

    【解决方案4】:

    您可以在 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
    

    【讨论】:

    • +1 Python 有所以 很多有用的模块。看来我每天都在学习一个新的。
    • 这是手动遍历差异;当然,使用difflib.restore 可以更轻松地恢复两个字符串之间的差异
    • 谢谢!但我不确定这是否是内存效率。列表(difflib.ndiff(“afrykanerskojęzyczny”,“nieafrykanerskojęzyczny”))['+ n','+ i','+ e','a','f','r','y','k' ,'a','n','e','r','s','k','o','j','ę','z','y','c',' z', 'n', 'y']
    • ndiff 是一个生成器,因此它的内存效率很高。您正在调用list,它将单独生成的字符比较转换为它们的完整列表。如果你不调用list,你一次只会有几个内存。
    • 也适用于 Python 2(对我而言)我建议询问具体来源和具体输出的问题。我无法在 cmets 中调试...
    【解决方案5】:

    您可以查看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'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 2013-02-04
      • 2011-08-22
      相关资源
      最近更新 更多