Home > Enterprise >  Specify the consecutive values (zeros) and remove them but only if they are consecutive
Specify the consecutive values (zeros) and remove them but only if they are consecutive

Time:03-02

I have this list of values:

A = [0,0,1,2,3,4,5,6,0,6,6,8,8,0,0,2,3,4,5,12,45,-0,-0,-9,-2,3,-0,-2,-2,-2]

I want to get this list of values for the output :

A = [1,2,3,4,5,6,0,6,6,8,8,2,3,4,5,12,45,-9,-2,3,-0,-2,-2,-2]

Basically, I want to drop the consecutive zeros only, and keep all the other values.

Do you have any idea on how i can do that ? I tried this one but i know there will be in index error :

X = []
for j in range(len(A)):
    if A[j] != 0 and A[j 1] != 0:
        X.append(A[j])
    else:
        print('lol')
print(X)```

CodePudding user response:

You can use itertools.groupby and itertools.chain:

from itertools import groupby, chain

out = list(chain.from_iterable(G for k,g in groupby(A)
                               if len(G:=list(g))<2 or k!=0))

Explanation:

groupby will group the consecutive values. For each group, if the length is no more than 1 or the key (=value) is not 0, keep it. Finally chain all the groups together and convert to list.

Note that groupby returns iterators so I am using an assignment expression to perform the conversion.

output:

[1, 2, 3, 4, 5, 6, 0, 6, 6, 8, 8, 2, 3, 4, 5, 12, 45, -9, -2, 3, 0, -2, -2, -2]

CodePudding user response:

With itertools:

from itertools import groupby

X = [x
     for x, [*xs] in groupby(A)
     if x or len(xs) == 1
     for x in xs]

Alternatively:

X = []
for x, [*xs] in groupby(A):
    if x or len(xs) == 1:
        X  = xs        

Or taking any x that's not zero or where the previous and next values are not zero (padding with 1):

X = [x
     for p, x, n in zip([1] A, A, A[1:] [1])
     if x or p and n]

CodePudding user response:

if u dont want to import itertools and prefer list comprehension

A = [i for index,i in enumerate(A) if i!=0 or index not in [0,len(A)] and A[index-1]!=i and A[index 1]!=i ]

note that this expressions uses the precedence of and operator over or operator

enumerate is used too

CodePudding user response:

Here's a more simple and easy method to solve your problem

A = [0,0,1,2,3,4,5,6,0,6,6,8,8,0,0,2,3,4,5,12,45,-0,-0,-9,-2,3,-0,-2,-2,-2]
A=[f"'{str(int)}'" for int in A]
a=",".join(A).replace("'0'","").replace("'","").split(",")
b=[i for i in a if i != ""]
c=[int(i) for i in b]
d_output=[1,2,3,4,5,6,0,6,6,8,8,2,3,4,5,12,45,-9,-2,3,-0,-2,-2,-2]
if c==d_output:
      print(1)

Output: 1 i.e Your desired output

If you want to specify the value, then you can wrap it up in a function as below:

def remove_con(l,val):
      A=[f"'{str(int)}'" for int in l]
      a=",".join(A).replace(f"'{val}'","").replace("'","").split(",")
      b=[i for i in a if i != ""]
      c=[int(i) for i in b]
      return c
print(remove_con(A,0))
  • First, I have converted the integers in list to a string.
  • Then joined them using .join method, replaced "'0'" with "" using .replace method, then spited the list by "," using .split method.
  • Then removed the empty element i.e "" elements.
  • Then again converted the string into integers.

I have noticed a silly mistake in your code:

X = []
for j in range(len(A)): # Mistake here
    if A[j] != 0 and A[j 1] != 0: # if we bypassed the above error we can also get error here
        X.append(A[j])
    else:
        print('lol')
print(X)

The problem is when the i is at last index of the list, there would be no other index but you have hard-coded to search for index 1, so it would throw an error.

There are 2 method to solve this:

  • Use try and except.
  • Replace range(len(A) to range(len(A)-1).

Useful references:

  • Related