One handy list mutation function is
remove, which removes the first occurrence of
a particular value from a list (finding the
index of the item with that value and deleting it).
Suppose we would like something more power, a RemoveAll
function, which removes all items with a given
value. As an example, for a list S = [2,2,2,2] and
the call RemoveAll(S,2), we expect that S becomes
empty as a result.
Removing an item from a list can be done either by slice assignment (replacing by an empty slice) or more conventionally, using the del statement. The only tricky thing about using del is that indices change each time an item is deleted. For instance, with X = ["go","so","to"], the statement del X[0] decrements the indicies of "so" and "to". That throws doubt on the strategy of just finding all the indices of the value to be removed and using del.
One clever below is to reverse the order of using del, so that only a larger index is used before a smaller one.
def deletor(SomeList,Index): |
del SomeList[Index] |
return None |
def RemoveAll(M,Val): |
places = [ i for i in range(len(M)) if M[i]==Val ] |
places.reverse() |
[ deletor(M,j) for j in places ] |
return None |
Example = [4,1,2,5,2,2,7,2,10,2] |
RemoveAll(Example,2) |
print Example |
But what if we cannot find such a clever idea? There is a far simpler idea: using slice assignment, an entire list can be replaced by a new version. To the caller, it will appear that the function mutated the list. The version of RemoveAll below has equivalent behavior to the one above. This second version is far simpler to understand.
def RemoveAll(M,Val): |
newM = [ e for e in M if e != Val ] |
M[:] = newM |
return None |
Example = [4,1,2,5,2,2,7,2,10,2] |
RemoveAll(Example,2) |
print Example |