Python remove from list acting strange when used inline
Question:
I want to loop through a list and remove a single element at a time:
l1 = ["a", "b"]
for l in l1:
l2 = l1[:]
l2.remove(l)
print(l2)
# ['b']
# ['a']
The behavior of the code changes when I use the remove call inline:
l1 = ["a", "b"]
for l in l1:
l2 = l1[:].remove(l)
print(l2)
# None
# None
Any idea what is happening? Is this an artefact of remove()
or a more general issue with functions that use mutability of objects?
Thanks
Answers:
Note that remove()
does not return anything. That is why l2
is always None
in your second example. The change is only applied to l1
.
In your first example example the list is duplicated into l2
and then an element is removed from l2
.
The problem is that when you excecute the line:
l2 = l1[:].remove(l)
you are doing this:
x = l1[:]
l2 = x.remove(l)
As you can see you are assinging to l2
the result of apply the method remove
on x
. The element will be removed, but remove
always return None
, that’s why l2
is None
.
The below code will do the job.
l1 = ["a", "b", "c", "d"]
for a,b in enumerate(l1):
l2 = l1[:].pop(a)
print(l2)
and that’s because .pop() function actually removes and returns it’s value, in the other hand .remove() returns None (and that’s what you get).
Happy Coding.!!!
Actually, the remove()
function returns None
, rather than the list with element removed.
Moreover, remove()
delete the element in O(N) complexity, which is cumbersome for your demand. I prefer to adopt the following approach
for idx in range(len(l1)):
l2 = l1[:idx] + l1[idx+1:]
print(l2)
I want to loop through a list and remove a single element at a time:
l1 = ["a", "b"]
for l in l1:
l2 = l1[:]
l2.remove(l)
print(l2)
# ['b']
# ['a']
The behavior of the code changes when I use the remove call inline:
l1 = ["a", "b"]
for l in l1:
l2 = l1[:].remove(l)
print(l2)
# None
# None
Any idea what is happening? Is this an artefact of remove()
or a more general issue with functions that use mutability of objects?
Thanks
Note that remove()
does not return anything. That is why l2
is always None
in your second example. The change is only applied to l1
.
In your first example example the list is duplicated into l2
and then an element is removed from l2
.
The problem is that when you excecute the line:
l2 = l1[:].remove(l)
you are doing this:
x = l1[:]
l2 = x.remove(l)
As you can see you are assinging to l2
the result of apply the method remove
on x
. The element will be removed, but remove
always return None
, that’s why l2
is None
.
The below code will do the job.
l1 = ["a", "b", "c", "d"]
for a,b in enumerate(l1):
l2 = l1[:].pop(a)
print(l2)
and that’s because .pop() function actually removes and returns it’s value, in the other hand .remove() returns None (and that’s what you get).
Happy Coding.!!!
Actually, the remove()
function returns None
, rather than the list with element removed.
Moreover, remove()
delete the element in O(N) complexity, which is cumbersome for your demand. I prefer to adopt the following approach
for idx in range(len(l1)):
l2 = l1[:idx] + l1[idx+1:]
print(l2)