Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove certain consecutive duplicates in list

I have a list of strings like this:

['**', 'foo', '*', 'bar', 'bar', '**', '**', 'baz']

I want to replace the '**', '**' with a single '**', but leave 'bar', 'bar' intact. I.e. replace any consecutive number of '**' with a single one. My current code looks like this:

p = ['**', 'foo', '*', 'bar', 'bar', '**', '**', 'baz']
np = [p[0]]
for pi in range(1,len(p)):
  if p[pi] == '**' and np[-1] == '**':
    continue
  np.append(p[pi])

Is there any more pythonic way to do this?

like image 847
user408952 Avatar asked Dec 17 '22 16:12

user408952


2 Answers

Not sure about pythonic, but this should work and is more terse:

star_list = ['**', 'foo', '*', 'bar', 'bar', '**', '**', 'baz']
star_list = [i for i, next_i in zip(star_list, star_list[1:] + [None]) 
             if (i, next_i) != ('**', '**')]

The above copies the list twice; if you want to avoid that, consider Tom Zych's method. Or, you could do as follows:

from itertools import islice, izip, chain

star_list = ['**', 'foo', '*', 'bar', 'bar', '**', '**', 'baz']
sl_shift = chain(islice(star_list, 1, None), [None])
star_list = [i for i, next_i in izip(star_list, sl_shift) 
             if (i, next_i) != ('**', '**')]

This can be generalized and made iterator-friendly -- not to mention more readable -- using a variation on the pairwise recipe from the itertools docs:

from itertools import islice, izip, chain, tee
def compress(seq, x):
    seq, shift = tee(seq)
    shift = chain(islice(shift, 1, None), (object(),))
    return (i for i, j in izip(seq, shift) if (i, j) != (x, x))

Tested:

>>> list(compress(star_list, '**'))
['**', 'foo', '*', 'bar', 'bar', '**', 'baz']
like image 150
senderle Avatar answered Dec 25 '22 11:12

senderle


This is in my opinion pythonic

result = [v for i, v in enumerate(L) if L[i:i+2] != ["**", "**"]]

the only "trickery" being used is that L[i:i+2] is a list of one element when i == len(L)-1.

Note that of course the very same expression can also be used as a generator

like image 33
6502 Avatar answered Dec 25 '22 12:12

6502