Home > OS >  Python- Need to search a list for adjacent duplicate values and replace the adjacent
Python- Need to search a list for adjacent duplicate values and replace the adjacent

Time:10-29

this is an example list:

mylist = [0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1]

I need to search the list for adjacent 0 until no zeros are adjacent. My needed output-

newlist = [0,x,1,0,1,0,x,x,1,0,x,x,x,1,0,x,x,1,0,1,0,x,1]

so I retain a single zero at its correct index, but replace its adjacents with "x". I am new to python and have take some very unsuccessful stabs at it.

I tried creating a while loop but I'm sad cuz bad.

CodePudding user response:

Zip the list together with a lagged copy of itself and use a list comprehension to produce the new list:

newlist = ["x" if a == b == 0 else b for a, b in zip([None]   mylist, mylist)]

I understood from your question that you are only looking for duplicate zeroes. But if you want to replace all duplicates, just remove the == 0:

newlist = ["x" if a == b else b for a, b in zip([None]   mylist, mylist)]

CodePudding user response:

You can achieve this using itertools.groupby():

from itertools import groupby

mylist = [0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1]
new_list = []

for _, j in  groupby(mylist):
    new_list.append(next(j))
    for _ in j:
        new_list.append('x')
 
# which will return you `new_list` as: 
#    [0, 'x', 1, 0, 1, 0, 'x', 'x', 1, 0, 'x', 'x', 'x', 1, 0, 'x', 'x', 1, 0, 1, 0, 'x', 1]

Here's an one liner to achieve this with additional usage of itertools.chain.from_iterable():

from itertools import groupby, chain 

new_list = list(chain.from_iterable((next(j), *['x' for _ in j]) for _, j in  groupby(mylist)))

# which will return you `new_list` as: 
#   [0, 'x', 1, 0, 1, 0, 'x', 'x', 1, 0, 'x', 'x', 'x', 1, 0, 'x', 'x', 1, 0, 1, 0, 'x', 1]

CodePudding user response:

This is likely the most simple and efficient solution. Using the walrus operator to assign the last number seen during iteration in a comprehension.

my_list = [0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1]

last = None
output = ['x' if last == n else (last := n) for n in my_list]

Output:

[0, 'x', 1, 0, 1, 0, 'x', 'x', 1, 0, 'x', 'x', 'x', 1, 0, 'x', 'x', 1, 0, 1, 0, 'x', 1]
  • Related