-1

This is my code so far

def filter_list2(elements):
    for a in elements:
        if a == (int(a) or float(a)) and a >= 1 and a < 50:
            elements.append(a)
        else:
            elements.pop(a)
    return elements

I want to change the following list:

filter_list2([0,10,55])

Into this:

[10]

I know pop is out of range. Is there something im missing? How can I convert my list into my result. Is pop the wrong approach?

EDIT:

def filter_list2(elements):
    for a in elements:
        if a == (int(a) or float(a)) and a >= 1 and a < 50:
            continue
        else:
            elements.remove(a)
    return elements

Does not work for 'abc'. How can I fix it?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • 1
    `a == (int(a) or float(a))` doesn't do what you think it does: [How to test multiple variables against a value?](https://stackoverflow.com/questions/15112125/how-to-test-multiple-variables-against-a-value). If you're checking what type it is you can use `isinstance(a, (int, float))` – Patrick Haugh Nov 04 '18 at 23:05
  • 1
    Be careful, this for loop will never end and grow your list until you run out of memory as soon as one element get trough the filter. – Niko B Nov 04 '18 at 23:12
  • @PatrickHaugh I think what the OP wants is to check if a string containing a number which is between 1 and 50, in this case, it still is wrong, but more logic... – J Faucher Nov 05 '18 at 00:23
  • the question needs to be clearer from the get go... otherwise the solution will never match. If you change the finish line after each answer, you will frustrate those who are answering and likely end up with downvotes – Sina Khelil Nov 05 '18 at 16:11

4 Answers4

1
list = [0, 10, 50]
new_list = [item for item in list if isinstance(item, (int, float)) and 50 > item >= 1]

List comprehension for the win...

no need for a function when a single line will do

Edit:

An answer to the updated question without converting the item in the list:

def filter_list(my_list):
    new_list = []
    for item in my_list:
        try:
            int(item)
        except ValueError:
            try:
                float(item)
            except ValueError:
                continue
            else:
                if 50 > float(item) >= 1:
                    new_list.append(item)
                else:
                    continue
        else:
            if 50 > int(item) >= 1:
                new_list.append(item)
            else:
                continue
    return new_list

my_list = [0, 10, 50, 'abc', '20', '13.3333']


print(filter_list(my_list))

ugly but functional

Community
  • 1
  • 1
Sina Khelil
  • 2,001
  • 1
  • 18
  • 27
0

pop() removes the element present at index in the list not the element itself. What this means is, it accept index number, not the element

Sufiyan Ghori
  • 18,164
  • 14
  • 82
  • 110
0

You're going to want to use remove which removes a particular item from the list. I'm not sure what you're trying to do with a == (int(a) or float(a)) For a direct translation, you could use:

def filter_list2(elements):
    for a in elements:
        if 1 <= a < 50:
            continue
        else:
            elements.remove(a)
    return elements

But that's not very efficient since the remove method is linear and therefore this filter is quadratic. Instead, you can delete by index:

def filter_list2(elements):
    for n, a in enumerate(elements):
        if not(1 <= a < 50):
            del elements[n]
    return elements

If you want to filter out all strings, you can do the following:

def filter_list2(elements):
    for n, a in enumerate(elements):
        if not(1 <= a < 50) or not(isinstance(a, (int, float))):
            del elements[n]
    return elements
Cory Nezin
  • 1,551
  • 10
  • 22
  • a == (int(a) or float(a)) --> I only want to output int and floats in the list – Marcel Hlmn Nov 04 '18 at 23:11
  • your code is right! But if I have a list with a string in it, it won't work. – Marcel Hlmn Nov 04 '18 at 23:13
  • All right, as Patrick Haugh mentioned, that's not how you test that. Python will first evaluate what's in the parenthesis (int(a) or float(a)) which will be 0.0 if a is 0 or 0.0, otherwise it will be int(a). – Cory Nezin Nov 04 '18 at 23:17
  • I added if a == (int(a) or float(a)) and a >= 1 and a < 50: this instead of if 1 <= a < 50: and now strings are removed automatically. Now the code works as intended – Marcel Hlmn Nov 04 '18 at 23:17
  • Be careful, that's not the right way to check for that, for instance if you have the string 'asdf' using int('asdf') will throw an error. You should instead do `if isinstance(a, str): elements.remove(a)` – Cory Nezin Nov 04 '18 at 23:20
  • def filter_list2(elements): for a in elements: if a == (int(a) or float(a)) and a >= 1 and a < 50: continue else: elements.remove(a) return elements no errors here. Doesn't matter if I put a string into a list or not – Marcel Hlmn Nov 04 '18 at 23:25
  • Did you test it with the string 'asdf'? – Cory Nezin Nov 04 '18 at 23:40
  • EDIT: You are right... how do I fix it? Edited the code above so you can see. – Marcel Hlmn Nov 04 '18 at 23:55
0

You don't wanna use something which edit your list boundaries while you are working on it.

I mean something like

for i in myList :
    myList.pop(anything)

is IMHO a bad idea since i will take all values of list before the beginning of the loop which might cause some issues (out of range).

You might prefer

tempList = []
for i in range(0,len(myList)) :
    if myList[i] == ... :
        tempList.append(i)

for i in tempList :
    myList.pop(i)

With that said, from what I understand, you want to filter out any string in a list of "things" (which may contain strings likes "abc" and number formatted as string likes "123" or "-1.2".)

You should then check if the input is a float/int using something like

try :
    float(in)
except ValueError :
   #Not a float nor int

So... in your case, I would go for

def filter_list2(elements):
    tempList = []
    for i in range(0,elements):
        try :
            temp = float(elements[i])
        except ValueError :
            tempList.append(i)

        if 1.0 <= temp < 50.0:
            continue
        else:
            tempList.append(i)
    for i in tempList :
        elements.pop(i)
    return elements
J Faucher
  • 988
  • 6
  • 14