Replace sublist with different-length sublist in python, like string.replace

Viewed 202

I am looking for a function like string.replace, but for lists.

For example, with string.replace:

>>> s="abcd abcd"
>>> s.replace("bc", "XYZ")
'aXYZd aXYZd'

So the list version of the same thing would be like this:

>>> l=['a','b','c','d',' ', 'a','b','c','d']
>>> l.replace(['b','c'], ['X','Y','Z'])
['a','X','Y','Z',d,' ','a','X','Y','Z',d]

Note: this is not just substituting single elements of the list with something else. It is replacing all occurrences of a sublist with a different sublist potentially having a different length - just like string.replace() does for substrings.

(The lists I'm actually working with are not actually lists of characters so converting to/from strings won't work.)

2 Answers

There is no operation to search a list for a sublist. However, once you know the location. the operation is easy.

def listfind( haystack, needle ):
  for i in range(len(haystack)-len(needle)):
      if haystack[i:i+len(needle)] == needle:
          return i
  return -1

def listreplace( old, new, haystack ):
    n = listfind( haystack, old )
    if n < 0:
        return haystack
    return haystack[0:n] + new + haystack[n+len(old):]

l=['a','b','c','d',' ', 'a','b','c','d']
l1 = listreplace( ['b','c'], ['X','Y','Z'], l )
print( l1 )

Output:

['a', 'X', 'Y', 'Z', 'd', ' ', 'a', 'b', 'c', 'd']

i tried writing in python


def replaceSubList(myList,listToReplace,listToBeReplacedWith):
    idx=0
    val=True
    while val:
        if myList[idx:].__contains__(listToReplace[0]) and myList.__len__()>=idx+myList[idx:].index(listToReplace[0])+listToReplace.__len__():
            idx=idx+myList[idx:].index(listToReplace[0])
            if listToReplace==myList[idx+myList[idx:].index(listToReplace[0]):idx+myList[idx:].index(listToReplace[0])+listToReplace.__len__()]:
                myList=myList[0:idx]+listToBeReplacedWith+myList[idx+listToReplace.__len__():]
            elif(idx<myList.__len__()):
                idx+=1
            else:
                val=False
        else:
            val=False

    print(myList)

replaceSubList([1,2,3,4,5,6,7,8,4,12,3,4,5,1,2,3,4,5,6,5,4],[4,5], [110,130,170,200]) 
Related