Reputation: 113
I have a list of lists :
W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
From each list in W
, I want to remove the zero entries.
I have tried the following :
for idx in range(len(W)):
W[idx].remove(0)
print(W)
But it will always return
[[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
Nothing has changed here. I am aware of the fact that I cannot change an object while I am iterating over it, however as I am not iterating over W
but over len(W)
, I don't see why my code wouldn't work.
What am I doing wrong?
Upvotes: 1
Views: 837
Reputation: 20490
A simple list comprehension should be enough.
W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
li = [ [j] for i in W for j in i if j!=0]
print(li)
#[[5.0], [5.0], [5.0], [5.0]]
Upvotes: 1
Reputation: 61335
Since there are more than 1 zeros in each sublist, we have to use two for
loops, if you want to stick with a loop based solution.
In [75]: for lst in W:
...: num_zeros = lst.count(0)
...: for _ in range(num_zeros):
...: lst.remove(0)
In [76]: W
Out[76]: [[5.0], [5.0], [], [5.0], [5.0]]
Now, your code:
In [79]: for idx in range(len(W)):
...: W[idx].remove(0)
...: print(W)
yields the solution:
[[5.0, 0, 0, 0], [5.0, 0, 0], [0, 0], [5.0, 0, 0], [5.0, 0, 0]]
which we can see is short of 1 zeros from the counts of zeros in the input list. This is because remove(obj)
will remove only the first occurrence of the object.
Upvotes: 0
Reputation: 21
I would say it's better to use filter with a lambda expression in order to filter out the zero values.
for idx in range(len(W)):
W[idx]=list((filter(lambda a: a != 0, W[idx])))
print(W)
This will give you the next output:
[[5.0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
[[5.0], [5.0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
[[5.0], [5.0], [], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
[[5.0], [5.0], [], [5.0], [5.0, 0, 0, 0]]
[[5.0], [5.0], [], [5.0], [5.0]]
Upvotes: 2
Reputation: 2763
As avloss said, that remove only removes the first occurrence. Do a list comprehension.
for idx in range(len(W)):
W[idx] = [i for i in W[idx] if i != 0]
print(W)
and as @meowgoesthedog suggested, you could do an overall list comprehension:
W = [lst[item for item in lst if item !=0] for lst in W]
Upvotes: 6
Reputation: 6920
You can use a list comprehension and filter function to delete the items having zero value in every sublist of W
:
W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
nw = [list(filter(lambda a: a != 0, k)) for k in W]
OUTPUT :
[[5.0], [5.0], [], [5.0], [5.0]]
Upvotes: 2
Reputation: 2636
if you want to remove all 0
elements you can user list comprehension and filter:
W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
for idx in range(len(W)):
W[idx] = [i for i in W[idx] if i != 0]
print(W)
output looks like this:
[[5.0], [5.0], [], [5.0], [5.0]]
Upvotes: 2
Reputation: 2636
This is because l.remove(0)
means remove first occurrence of that element. to remove element by index you can use del
W = [[5.0, 0, 0, 0, 0], [5.0, 0, 0, 0], [0, 0, 0], [5.0, 0, 0, 0], [5.0, 0, 0, 0]]
for idx in range(len(W)):
del W[idx][0]
print(W)
this produces
[[0, 0, 0, 0], [0, 0, 0], [0, 0], [0, 0, 0], [0, 0, 0]]
Upvotes: -2