Python 比较字符串中的字符

Python 比较字符串中的字符,python,string,list,Python,String,List,给定两个字符串作为参数,当iff返回true时,第一个单词可以通过仅更改一个字母由第二个单词组成。我的做法是: def differ(word_one, word_two): '''(str, str) -> bool Returns true iff word_two can be formed from word_one by changing exactly one letter. >>> differ('cat', 'bat')

给定两个字符串作为参数,当iff返回true时,第一个单词可以通过仅更改一个字母由第二个单词组成。我的做法是:

def differ(word_one, word_two):
    '''(str, str) -> bool

    Returns true iff word_two can be formed from word_one by changing
    exactly one letter.

    >>> differ('cat', 'bat')
    True
    >>> differ('word', 'sword')
    False

    '''
    temp_list = []
    # If the length of the first string is equal to the length of the
    # second string, iterate over the letters in the first string and
    # if the letter in the first string does not equal to the letter 
    # in the second string append the letter to temp_list
    if len(word_one) == len(word_two):
        for char in word_one:
            if char != word_two[word_one.index(char)]:
                temp_list.append(char)
    if len(temp_list) == 1:
        return True
    else:
        return False

根据描述,我的代码似乎工作正常,但是有没有更简单的方法呢?

看起来像是一个简单的
zip
(加上一些长度检查),不是吗

这确实依赖于一个有些模糊的事实,即在算术上下文中,
True==1
False==0
。e、 g.
True+True+True+False==3

例如:

>>> def differ(word1, word2):
...     return ((len(word1) == len(word2)) and 
...             (sum(a != b for a, b in zip(word1, word2)) == 1))
... 
>>> differ('cat', 'bat')
True
>>> differ('cat', 'hat')
True
>>> differ('cat', 'can')
True
>>> differ('cat', 'car')
True
>>> differ('cat', 'bar')
False
另一种使用地图的方法

import operator
def differ(w1, w2):
    return len(w1) == len(w2) and sum(map(operator.ne, w1, w2)) == 1
使用
sum
的版本的问题在于,即使在开始时已经存在一些差异,它们也会迭代整个字符串。所以有一个短路版本

import operator, itertools
def differ(w1, w2):
    it = itertools.imap(operator.ne, w1, w2)
    return len(w1) == len(w2) and any(it) and not any(it)

如果
word\u one
有重复的字母,则使用
word\u one.index(char)
会有问题。例如,
abracadabra
abrzdzbrz
会错误地说字母没有变化。仅供参考:这是问题的一个子集。如果这不仅仅是为了练习,不要重新发明轮子-在
difflib
中重用已经存在的代码,还有,为什么要在
//code>中添加“注释”。当然,它们不在您的实际代码中——如果它们在,它就不会运行;-)。为什么不使用常规的python注释呢?这将使复制/粘贴代码并运行代码变得更加容易。您还需要检查单词的长度是否相同。不要忘记最短字符串末尾的zip stop
izip_longest
无法正常工作。对于“abc”和“abcd”,它将返回true。还要注意,在python3.x上,
map
选择了
zip
@mgilson的较短序列截断行为,显然需要更多的咖啡。是的,imap也这样做。@mgilson,你能在我喝咖啡的时候帮我检查一下短路版本吗?短路对我来说很好。仍然不太习惯那种
任何
技巧(尽管我知道它是如何工作的)。也就是说,我认为我们认为第一个
地图
版本是不好的。它为
“hat”
“hats”
提供了一个假
True
,因为在python2.x上,
None!=“s”
True
,因此您仍然需要进行显式长度检查。
import operator
def differ(w1, w2):
    return len(w1) == len(w2) and sum(map(operator.ne, w1, w2)) == 1
import operator, itertools
def differ(w1, w2):
    it = itertools.imap(operator.ne, w1, w2)
    return len(w1) == len(w2) and any(it) and not any(it)