Reputation: 23
Lets say I have two lists:
x=[1,0,0,3,2,5,6,0,4,2]
y=[e,r,g,d,e,w,t,y,t,r]
I want to remove all the zeros from the "x" list, and all values correspond to the position of the zeros from the "y" list, such that in the end:
x=[1,3,2,5,6,4,2]
y=[e,d,e,w,t,t,r]
I tried:
for i in range(len(x)):
if x[i]==0:
del x[i]
del y[i]
return x
return y
However, I realized that as the element in the i-th index position gets deleted, the range changes. Is there a better loop or method I can implement.
Upvotes: 2
Views: 1077
Reputation: 609
You can do this in one line with a list comprehension:
result = [[x[i], y[i]] for i in range(len(x)) if x[i] != 0]
Then you have a list of the pairs, which you can quickly get back into your original format with numpy:
import numpy as np
resultX = np.array(result)[:, 0]
resultY = np.array(result)[:, 1]
Upvotes: 0
Reputation: 384
aha, I spent a super long time trying to figure this out when I needed it. Glad you dont have to go through it.
def list_del(inp,poss):
'''delete items at indexes given in the list poss from list inp'''
try:
assert(isinstance(inp,list))
except AssertionError:
raise(AssertionError('input has to be a list, if numpy, using np.delete'))
inpu = inp
pos = 0
for i in list(sorted(poss)):
del inpu[i-pos]
pos += 1
return inpu
example:
list_del([0,1,2,3,4],[0,2,-1])
returns
[1, 2]
In your case:
for i in list(x):
if i == 0:
deleting.append(i)
list_del(x,deleting)
list_del(y,deleting)
Upvotes: 0
Reputation: 36033
Instead of deleting, you can construct new lists:
x = [1, 0, 0, 3, 2, 5, 6, 0, 4, 2]
y = 'e,r,g,d,e,w,t,y,t,r'.split(',')
x, y = zip(*[
(xe, ye)
for xe, ye in zip(x, y)
if xe != 0
])
print(x, y)
Upvotes: 3
Reputation: 51063
The problem is that when you delete an element from a list, all the later indices get shifted backwards by 1 so that there's no gap left by what you deleted. The earlier indices, however, remain untouched; so the simple fix is to iterate over the indices backwards.
def remove_zeros(x, y):
for i in reversed(range(len(x))):
if x[i] == 0:
del x[i]
del y[i]
return x, y
Note that if you want to return two results, you have to return them as a tuple; the second return
statement won't be reached otherwise.
Upvotes: 3