Here is a method without buffer that does not copy as it only looks at one character at a time:
from itertools import islice, izip s = "to_be_or_not_to_be" pos = [15, 2, 8] length = len(s) for start1, start2 in izip(pos, islice(pos, 1, None)): pref = 0 for pos1, pos2 in izip(xrange(start1, length), xrange(start2, length)): if s[pos1] == s[pos2]: pref += 1 else: break print pref
I use islice , izip and xrange if you are talking about potentially very long lines.
I also could not resist this "One Liner", which does not even require indexing:
[next((i for i, (a, b) in enumerate(izip(islice(s, start1, None), islice(s, start2, None))) if a != b), length - max((start1, start2))) for start1, start2 in izip(pos, islice(pos, 1, None))]
One final method using os.path.commonprefix :
[len(commonprefix((buffer(s, n), buffer(s, m)))) for n, m in zip(pos, pos[1:])]