cd123
cd123

Reputation: 521

Delete items from a list equal to a number from a list made of strings and numbers

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

Answers (5)

A. Grinenko
A. Grinenko

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:

  • None
  • False
  • zero of any numeric type, for example, 0, 0.0, 0j.
  • any empty sequence, for example, '', (), [].
  • any empty mapping, for example, {}.
  • instances of user-defined classes, if the class defines a bool() or len() method, when that method returns the integer zero or bool value 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

Nick is tired
Nick is tired

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

Shubho Shaha
Shubho Shaha

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

Leszek Kicior
Leszek Kicior

Reputation: 193

Try this:

x = [h for h in x if h != 0]

Some small bits of advice:

  1. You don't have to specify else: pass.
  2. 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
    
  3. 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

farax
farax

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

Related Questions