Reputation: 521
I have a list of the following structure which is simplified for the purpose of this question:
x = ["f","f","f",0,"f",0,0,0"f","f"]
Where "f" represents a file path as a string. What I wish to do is remove all elements from the list equal to zero. I have tried iterating over like so:
for h in range(len(x)):
if x[g] == "0":
del x[g]
else:
pass
This has not worked as deleting from a list being iterated over does not work and it seems to be like list comprehension is the answer I am looking for but I can't seem to get the formatting down:
x = [h for h in range(len(x)) if h != 0]
So my final desired output would be:
x = ["f","f","f",f","f",f"]
How do I go about achieveing this?
EDIT: Patrick's answer in the comments below is exactly what I was looking and solves this.
Upvotes: 2
Views: 112
Reputation: 331
I want also note that in a case when x is a large size list you may want iterator to be returned after list filtering because using iterator on a large data set may increase your performance (See Performance Advantages to Iterators? for more information). In this case you can use built-in filter(function, iterable) function that will return iterator in a Python 3.
x = ["f","f","f",0,"f",0,0,0,"f","f"]
for ch in filter(lambda sym: sym != 0, x):
print(ch)
As a result only elements not equal to 0 will be printed. See https://docs.python.org/3/library/functions.html#filter to get more information about the filter built-in.
Another approach is to use generator comprehension. The note here is that you will be able to iterate over the generator just once. But you will also have some benefits, each result will be evaluating and yielding on the fly so your memory will be conserved by using a generator expression instead.
Just use this example to use generator comprehension:
x = ["f","f","f",0,"f",0,0,0,"f","f"]
for ch in (sym for sym in x if sym !=0):
print(ch)
See more generator comprehension examples and advantages here https://www.python.org/dev/peps/pep-0289/
Also be accurate filtering results with True value testing.
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
So expression [sym for sym in x if sym]
will remove all False symbols (i.e. False, '', etc.) from your results. So be accurate using True value testing (see https://docs.python.org/3.6/library/stdtypes.html#truth-value-testing for more information).
Upvotes: 1
Reputation: 7055
The reason you can't do this looping forwards is because you're shortening the list as you go along, but if you loop backwards you won't have this issue:
>>> x = ["f","f","f","0","f","0","0","0","f","f"]
>>> for h in range(len(x)-1,-1,-1):
... if x[h] == "0":
... del x[h]
...
>>> x
['f', 'f', 'f', 'f', 'f', 'f']
Upvotes: 0
Reputation: 2139
I hope this piece of code will serve your purpose.
x = [i for i in x if i]
It's mean get all value from x which is not 0
Upvotes: 0
Reputation: 193
Try this:
x = [h for h in x if h != 0]
Some small bits of advice:
else: pass
.You can iterate directly over a list, i.e. instead of:
for i in range(len(x)):
x[i]
you can simply use:
for i in x:
i
if x[g] == "0"
would only check if x[g]
is equal to the string "0"
, not the actual number. Judging by your code, you want if x[g] == 0
instead.
Upvotes: 0
Reputation: 151
You can replace all 0 and "0" with:
li = ["f","f","f",0,"f",0,"0",0,"f","f"]
[y for y in l if y not in ("0",0)]
# results:
['f', 'f', 'f', 'f', 'f', 'f']
Upvotes: 0