我想知道两个字符串停止匹配的索引。
例如:
a = "happy birthday"
b = "happybirthday"
字符串a
和b
在索引5(基于0)上停止匹配。
我知道我可以像这样编写我的方法:
def compare_2_string(a, b):
for x in xrange(len(a)):
if a[x] != b[x]:
return x
但是有一种更简洁,更简洁的方式来做同样的逻辑吗?
答案 0 :(得分:4)
使用difflib:
>>> s1 = "happy birthday"
>>> s2 = "happybirthday"
>>> s = difflib.SequenceMatcher(None, s1, s2)
>>> m = s.get_matching_blocks()
>>> print m[0][2]
5
(m
是元组列表,每个元组的第3个元素是匹配的块的大小。在实际代码中,您要确保实际存在匹配所有,等等。)
答案 1 :(得分:2)
>>> next(itertools.dropwhile(lambda x: x[1][0] == x[1][1], enumerate(itertools.izip_longest(a, b))))[0]
5
答案 2 :(得分:2)
将next
与生成器表达式一起使用。这也适用于不同长度的字符串:
>>> from itertools import izip_longest
>>> next((i for i, (x, y) in enumerate(izip_longest(a, b)) if x != y), None)
5
答案 3 :(得分:1)
这是另一种方式:
(i for (i, (e1, e2)) in enumerate(zip(a, b)) if e1 != e2).next()
=> 5
答案 4 :(得分:1)
我也去了zip /枚举答案;我的感觉是'最Pythonic'形状是一个经典的函数,而不是围绕itertools或生成器表达式包裹next(),而是YMMV。我的是:
def compare_2_strings(s1, s2):
for charPos, (s1Char, s2Char) in enumerate(zip(s1, s2)):
if not s1Char == s2Char:
return charPos
如果字符串相同,则返回None(“缺少字符位置,它们不同”)。
追逐其他形状,我有:
def compare_2_strings(a, b):
import itertools
return len(list((itertools.takewhile(lambda s: operator.eq(*s), zip(a, b)))))
如果它们是相同的字符串,它将返回它们的长度。
这是更丑陋的,更长的代码,更少的Pythonic,和做得更多。你还想要什么?