2014-02-10 175 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