I currently use this code:
""" Replace all occurrences of subsequence a with b in list l """
def replace_subsequence(l,a,b):for i in range(len(l)):if(l[i:i+len(a)] == a):l[i:i+len(a)] = b
Example:
>>> l = [1,2,3]
>>> replace_subsequence(l,[2,3],[4])
>>> l
[1, 4]
Is there a more efficient and/or elegant way to do this ?
To improve efficiency, you can use the Boyer–Moore string search algorithm when searching for a sublist in a list
Code (credits)
def match(pattern, list):matches = []m = len(list)n = len(pattern)rightMostIndexes = preprocessForBadCharacterShift(pattern)alignedAt = 0while alignedAt + (n - 1) < m:for indexInPattern in xrange(n-1, -1, -1):indexInlist = alignedAt + indexInPatternx = list[indexInlist]y = pattern[indexInPattern]if indexInlist >= m:breakif x != y:r = rightMostIndexes.get(x)if x not in rightMostIndexes:alignedAt = indexInlist + 1else:shift = indexInlist - (alignedAt + r)alignedAt += (shift > 0 and shift or alignedAt + 1)breakelif indexInPattern == 0:matches.append(alignedAt)alignedAt += 1return matchesdef preprocessForBadCharacterShift(pattern):map = { }for i in xrange(len(pattern)-1, -1, -1):c = pattern[i]if c not in map:map[c] = ireturn mapif __name__ == "__main__":matches = match("ana", "bananas")for integer in matches:print "Match at:", integerprint (matches == [1, 3] and "OK" or "Failed")matches = match([1, 2, 3], [0, 1, 2,3 , 4, 5, 6])for integer in matches:print "list Match at:", integerprint (matches)