Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove Python list element

Tags:

python

list

I have two list,

l1 = [1,2,3,4,5,6]
l2 = [3,2]

what i want is to remove the element of list l1 which is in l2, for that i have done something like this,

for x in l1:
    if x in l2:
        l1.remove(x)

it gives output like

[1, 3, 4, 5, 6]

but the output should be like

[1, 4, 5, 6]

can any one shed light on this.

like image 321
Atul Arvind Avatar asked Nov 29 '22 08:11

Atul Arvind


2 Answers

This is easily explained like this.

consider the first array you have:

| 1 | 2 | 3 | 4 | 5 | 6 |

Now you start iterating

| 1 | 2 | 3 | 4 | 5 | 6 |
  ^

Nothing happens, iterator increments

| 1 | 2 | 3 | 4 | 5 | 6 |
      ^

2 gets removed

| 1 | 3 | 4 | 5 | 6 |
      ^

iterator increments

| 1 | 3 | 4 | 5 | 6 |
          ^

And voila, 3 is still there.

The solution is to iterate ove a copy of the vector e.g.

for x in l1[:]: <- slice on entire array
    if x in l2:
        l1.remove(x)

or to iterate in reverse:

for x in reversed(l1):
    if x in l2:
        l1.remove(x)

Which acts like this:

| 1 | 2 | 3 | 4 | 5 | 6 |
              ^

| 1 | 2 | 3 | 4 | 5 | 6 |
          ^

| 1 | 2 | 4 | 5 | 6 |
          ^

| 1 | 2 | 4 | 5 | 6 |
      ^

| 1 | 4 | 5 | 6 |
      ^

| 1 | 4 | 5 | 6 |
  ^
like image 129
Minion91 Avatar answered Dec 06 '22 10:12

Minion91


Why not making it a bit simpler? No need to actually iterate over l1 if we only want to remove elements present in l2:

for item in l2:
    while item in l1:
        l1.remove(item)

This gives you exactly the output desired...

Also, as commenters point out, if there is a possibility that we can have duplicates:

l1 = filter(lambda x: x not in l2, l1)

.. or many other variations using list comprehensions.

like image 24
petr Avatar answered Dec 06 '22 11:12

petr