find sublist inside list

Gerard Flanagan grflanagan at gmail.com
Tue May 5 06:22:43 EDT 2009


Matthias Gallé wrote:
> Hi.
> 
> My problem is to replace all occurrences of a sublist with a new element.
> 
> Example:
> Given ['a','c','a','c','c','g','a','c'] I want to replace all 
> occurrences of ['a','c'] by 6 (result [6,6,'c','g',6]).
> 

For novelty value:

from itertools import izip

def replace2(data, pattern):
     assert len(pattern) == 2
     pattern = tuple(pattern)
     icopy = iter(data)
     icopy.next()
     gen = izip(data, icopy)
     while True:
         item = gen.next()
         if item == pattern:
             yield '6'
             gen.next()
         else:
             yield item[0]

# works if list ends with ['a', 'c']
data = ['g', 'a', 'c', 'a', 'c', 'a', 'a', 'a', 'g', 'a', 'c']
want = 'g66aaag6'
assert ''.join(replace2(data, ['a', 'c'])) == want

# otherwise you lose the last element of the tail
data = ['g', 'a', 'c', 'a', 'c', 'a', 'a', 'a', 'g', 'a', 'c', 'c', 'g']
want = 'g66aaag6cg'
get = 'g66aaag6c'
assert not ''.join(replace2(data, ['a', 'c'])) == want
assert ''.join(replace2(data, ['a', 'c'])) == get

# fix by adding the pattern to the end of the data as a sentinel

def replace2(data, pattern):
     assert len(pattern) == 2
     def _replace2(data, pattern):
         pattern = tuple(pattern)
         icopy = iter(data)
         icopy.next()
         gen = izip(data, icopy)
         while True:
             item = gen.next()
             if item == pattern:
                 yield '6'
                 gen.next()
             else:
                 yield item[0]
     data = data + pattern
     return list(_replace2(data, pattern))[:-1]

data = ['g', 'a', 'c', 'a', 'c', 'a', 'a', 'a', 'g', 'a', 'c']
want = 'g66aaag6'
assert ''.join(replace2(data, ['a', 'c'])) == want

data = ['g', 'a', 'c', 'a', 'c', 'a', 'a', 'a', 'g', 'a', 'c', 'c', 'g']
want = 'g66aaag6cg'
assert ''.join(replace2(data, ['a', 'c'])) == want

print 'done'




More information about the Python-list mailing list