Tags

, ,

Recently, i faced an issue in my code, which made me realise the value of Immutability, also need to understand how everything works in deep.

Simply, say based on a condition, we need to remove elements in an array (List).
So its simple, loop through the array, if the fail_condition is true, remove the element.

logic to delete the array based on condition

def fail_cond(x): return x==2 or x==3

arr = [1,2,3,4,5,6]

for e in arr:
    print e
    if fail_cond(e): arr.remove(e)
#lets check the original array
print arr

cool, i am expecting the output to be [1,4,5,6]
[Try it out and see the answer yourself, change the fail_cond as you like eg: 1<e<4]

But its not!

It proves that the python, iterates through the array with index, and we are mutating the original array. so it fails to meet our general expectation. it might miss some elements because the array elements positions are changed (like shifting to the left).

original array: [1, 2, 3, 4, 5, 6] then while deleting 2, its next index is 2, so it picks arr[2] which is 4, since we deleted an element : [1, 3, 4, 5, 6]

1 [1, 2, 3, 4, 5, 6]
2 [1, 2, 3, 4, 5, 6]
4 [1, 3, 4, 5, 6]
5 [1, 3, 4, 5, 6]
6 [1, 3, 4, 5, 6]
[1, 3, 4, 5, 6]

So better way is to get a new copy of the array and remove it in original array of using filter, ( but it also depends because i had to do some more logic while looping over elements), or use a comprehension.

 filter(lambda e: fail_cond(e), copy_of_orignal_arry) 

Its reminds me of concurrentModificationException that we get in java 🙂

Question: this leads to another curious question, if its expecting the elements by index, then how come its not throwing array index out of bound exception lets say at the end? (also thinking in perspective of compiler optimizing the variable and puts it out of the loop…)

Maybe its not keeping initial length, but using len(arr) while iteration…

Advertisements