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
andexcept
. - Replace
range(len(A)
torange(len(A)-1)
.
Useful references: