2014-02-10 128 views
1

是否有函数比较两个字符串(相同长度)相差多少个字符?我的意思是只有替代。例如,AAA将与AAT相差1个字符。比较两个字符串的Python

+3

[Levenshtein distance](http://en.wikipedia.org/wiki/Levenshtein_distance)例如? – poke

回答

3

这是一个不错的zip功能用例!

def count_substitutions(s1, s2): 
    return sum(x != y for (x, y) in zip(s1, s2)) 

用法:

>>> count_substitutions('AAA', 'AAT') 
1 

从文档:

zip(...) 
    zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] 

    Return a list of tuples, where each tuple contains the i-th element 
    from each of the argument sequences. The returned list is truncated 
    in length to the length of the shortest argument sequence. 
+1

可能我建议避免从小写字母L开始的变量名?我以为你在比较11到 @ – mhlester

+0

@ mhlester:你有一个点。但是,字符串中几个字母的缩写是什么? – sjakobi

+0

如果它只用于理解,它并不重要。我完全支持你的x/y :) – mhlester

4

这将工作:

>>> str1 = "AAA" 
>>> str2 = "AAT" 
>>> sum(1 for x,y in enumerate(str1) if str2[x] != y) 
1 
>>> str1 = "AAABBBCCC" 
>>> str2 = "ABCABCABC" 
>>> sum(1 for x,y in enumerate(str1) if str2[x] != y) 
6 
>>> 

上述解决方案使用sumenumerategenerator expression


因为True可以计算为1,你甚至可以这样做:

>>> str1 = "AAA" 
>>> str2 = "AAT" 
>>> sum(str2[x] != y for x,y in enumerate(str1)) 
1 
>>> 

但我个人更喜欢第一个解决方案,因为它更清晰。

+0

美丽,谢谢 – goodcow

1

建立在什么戳说我会建议jellyfish包。它有几个距离度量,如你所要求的。从文档实例:

IN [1]: jellyfish.damerau_levenshtein_distance('jellyfish', 'jellyfihs') 
OUT[1]: 1 

或使用例如:

IN [2]: jellyfish.damerau_levenshtein_distance('AAA','AAT') 
OUT[2]: 1 

这将为许多不同的字符串长度工作,应该能够处理大多数的你扔东西吧。

1

与西蒙的答案类似,但你不必压缩的东西,只是调用结果元组的函数,因为这是什么map无论如何(和Python 2中的itertools.imap)。 operator有一个方便的功能。因此:

sum(map(operator.ne, s1, s2)) 
+0

可以将operator.ne替换为lambda函数吗? – goodcow

+0

@goodcow:当然,但我认为除了减少文件顶部的“导入”行数量外,我认为它不会改善任何情况:-) –

+0

不错!这个版本比我在Python 3.3上的版本快得多! – sjakobi