1

I am trying to write a function which will return True or False if the given number is not greater than 2. So simple, but the if condition is returning different outputs for same value '2'. The code I used is: The code I used is:

ele_list = [1,2,3,2]
for i in ele_list:
    if not i>2:
        print(i,False)
        ele_list.remove(i)
        print(ele_list)

The ouput I am receiving is:

1 False
[2, 3, 2]
2 False
[3, 2]

I am confused to see that the first 2 in the list is passing through the if condition but the second 2 in the list is not passing through the condition. Please help me figure out this..

Olian04
  • 6,480
  • 2
  • 27
  • 54

3 Answers3

1

Removing elements from the list you're looping over is generally a bad idea. What's happening here is that when you're removing an element, you're changing the length of the array, and therefor changing what elements are located at what indexes as well as changing the "goal" of the forloop.

Lets have a look at the following example:

ele_list = [4,3,2,1]

for elem in ele_list:
  print(elem)
  ele_list.remove(elem)
  1. In the first iteration of the loop elem is the value 4 which is located at index 0. Then you're removing from the array the first value equal to elem. In other words the value 4 at index 0 is now removed. This shifts which element is stored at what index. Before the removal ele_list[0] would be equal to 4, however after the removal ele_list[0] will equal 3, since 3 is the value that prior to the removal was stored at index 1.
  2. Now when the loop continues to the second iteration the index that the loop "looks at" is incremented by 1. So the variable elem will now be the value of ele_list[1] which in the updated list (after the removal of the value 4 in the previous iteration) is equal to 2. Then you're (same as before) removing the value at index 1 from the list, so now the length of the list just 2 elements.
  3. When the loops is about to start the third iteration it checks to see if the new index (in this case 2) is smaller than the length of the list. Which its not, since 2 is not smaller than 2. So the loop ends.

The simplest solutions is to create a new copy of the array and loop over the copy instead. This can easily be done using the slice syntax: ele_list[:]

ele_list = [1,2,3,2]

for elem in ele_list[:]:
  if not elem > 2:
    print(elem, False)
    ele_list.remove(elem)
    print(ele_list)
Olian04
  • 6,480
  • 2
  • 27
  • 54
1

the problem is that you're modifying your list as you're iterating over it, as mentioned in @Olian04's answer.

it sounds like what you really want to do, however, is only keep values that are > 2. this is really easy using a list comprehension:

filtereds_vals = [v for v in ele_list if v > 2]

if you merely want a function that gives you True for numbers greater than 2 and False for others, you can do something like this:

def gt_2(lst):
    return [v > 2 for v in lst]

or, finally, if you want to find out if any of the values is > 2 just do:

def any_gt_2(lst):
    return any(v > 2 for v in lst)
acushner
  • 9,595
  • 1
  • 34
  • 34
0

I think the problem here is how the remove function interacts with the for function.

See the documentation, read the "note" part: https://docs.python.org/3.7/reference/compound_stmts.html?highlight=while#grammar-token-for-stmt

This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole sequence

A possible solution, as suggested into the documentation:

ele_list = [1,2,3,2]
for i in ele_list[:]:
    if not i>2:
        print(i,False)
        ele_list.remove(i)
        print(ele_list)
"""
1 False
[2, 3, 2]
2 False
[3, 2]
2 False
[3]
"""
mellowonpsx
  • 56
  • 1
  • 1
  • 4