0

I want to write a for loop that tests two functions on a list. First one gives back an int, second a boolean. If boolean == False the function should remove the element from the list so in the end after calling the function L should have mutated. Here is an example.

def f(i):
    return i + 2

def g(i):
    return i > 5

L = [0, -10, 5, 6, -4]

def applyF_filterG(L, f, g):
    for i in L:
        if g(f(i)) == False:        
            L.remove(i)

L = [5, 6]

My problem is that with the function written above I get L = [-10, 5, 6] back because if i is removed, the i+1 turns into an i+2 because of the removed element. Does anybody know how to solve this? Big thanks!

Mickey Mahoney
  • 361
  • 1
  • 4
  • 15

2 Answers2

5

You should never remove elements from the list while iterating over it. just make a new list L1 equal to L and remove elements from L and iterate over L1.

def f(i):
    return i + 2

def g(i):
    return i > 5

L = [0, -10, 5, 6, -4]

def applyF_filterG(L, f, g):
    L1 = list(L)
    for i in L1:
        if g(f(i)) == False:        
            L.remove(i)


applyF_filterG( L, f, g )

print L
Ankit Vallecha
  • 708
  • 7
  • 17
2

Can you simplify this by just generating another list:

L = [0, -10, 5, 6, -4]
r = [a for a in L if a <= 5]

or something like that?

Hannu
  • 11,685
  • 4
  • 35
  • 51
  • The functions are just examples, they can change. That's why I can't be more specific in the loop – Mickey Mahoney Oct 04 '16 at 11:58
  • Then call a function r = [a for a in L if f(a) <= g()] It remains the same nevertheless. You need to create a new list instead of deleting items from the list you are looping through. After the loop you can then assign L=r. – Hannu Oct 04 '16 at 12:05