Reputation: 940
Question:
I have two longs lists, ~50,000 elements in each, that are the exact same size. List a contains 8 values (all different) followed by 16 zeroes which repeats until the end of the list, list b is a the result of a trigonometric function performed on the first list.
I'd like to remove all the zeroes from list a, and then every corresponding index from list b.
Example (all 1's and 2's for simplicity):
a = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2] ...
b = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2] ...
To become
a = [1,1,1,1,1,1,1,1,2,2] ...
b = [1,1,1,1,1,1,1,1,2,2] ...
In reality, every single element has a different value apart from zeroes, so I was thinking of a loop that scans list a for zeroes, and removes the elements at that index from both lists.
This is what I've come up with so far but I get an error 'list index out of range'
for i in range(len(a)):
if a[i] == 0:
a.remove(a[i])
b.remove(b[i])
else:
pass
Thanks
Upvotes: 3
Views: 3099
Reputation: 11590
One way to do it is
a = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2]
b = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2]
new_a = []
new_b = []
for i,j in zip(a,b):
if i:
new_a.append(i)
new_b.append(j)
a = new_a
b = new_b
print(a)
print(b)
which produces
[1, 1, 1, 1, 1, 1, 1, 1, 2, 2]
[1, 1, 1, 1, 1, 1, 1, 1, 2, 2]
Another (quicker) solution using the same approach but with list comprehensions is
new_a = [i for i in a if i]
b = [j for i,j in zip(a,b) if i]
a = new_a
Note: as you can see, there is no need to use indexing nor to look for the zero elements in the list on every iteration
Upvotes: 1
Reputation: 1711
a = [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2]
b = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2]
x = zip(a,b)
x = filter(lambda item: item[0] != 0, x)
a,b = map(list,zip(*x))
use zip
to combine list a and b, the result looks like:
[(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (2, 2), (2, 2)]
then filter the tuple
whose first element is 0.
last, unzip the result and convert to list
Before Python 3.0 you'd want to use itertools.izip if you have large numbers of elements.
Upvotes: 1
Reputation: 13550
this is better way i think for removing zeros:
sol 1
while a.count(0):
a.remove(0)
print a #[1,1,1,...,2]
or you can do this: sol2
for i in range(len(a)-1,-1,-1):
if a[i] == 0:
a.remove(a[i])
b.remove(b[i])
the reason your code is not working , is that when you start from zero and then use range(len(a)) assume range is 25, then you remove the 4th element, now your range is 24 and your list no longer has 25th element! so when in you for loop, i eqauls 24 you get index error(because by that time your list is smaller), but if you move from end of your list, when your list gets smaller,this problem won't occure
Upvotes: 0
Reputation: 12693
With numpy
's fancy indexing you can do it with a couple of lines of code:
import numpy as np
a = np.array(a)
b = np.array(b)[a != 0].tolist()
a = a[a != 0].tolist()
And consider using numpy
if you're working with large portions of data.
Upvotes: 3