比较字符串中的字符

时间:2013-12-09 00:05:01

标签: python string list

给定两个字符串作为参数返回true iff第一个单词可以通过改变一个字母从第二个单词形成。我接近这个的方式是:

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

根据描述,我的代码似乎工作得很好但是有更简化的方法吗?

2 个答案:

答案 0 :(得分:5)

看起来像一个简单的zip(加上一些长度检查),没有?

sum(a != b for a, b in zip(word1, word2)) == 1

这确实依赖于在算术上下文中有些模糊的事实,True == 1False == 0。例如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

答案 1 :(得分:3)

if len(word_one) == len(word_two):
    return sum(c!=d for c,d in zip(word_one, word_two)) == 1
return False   # optional - often None will do instead

使用地图的另一种方式。

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)