2

I am curious. How can I correctly iterate through a list, compare two values and delete the duplicate if it exists.

Here I created a nested for loop:

my_list =  [ 1, 2, 3, 4, 5 ]
temp = [1, 5, 6]

def remove_items_from_list(ordered_list, temp):
    # Removes all values, found in items_to_remove list, from my_list
        for j in range(0, len(temp)):
                for i in range(0, len(ordered_list)):
                        if ordered_list[i] == temp[j]:
                                ordered_list.remove(ordered_list[i])

But when I execute my my code I get an error:

  File "./lab3f.py", line 15, in remove_items_from_list
    if ordered_list[i] == items_to_remove[j]:

can anyone explain why?

This question, wanted to me compare two lists with one another, and these lists have two different lengths. If an item in list a matched a value in list b, we wanted then to delete it from list a.

  • 2
    You are removing items from the sequence you are iterating over... Don't do that. – Reblochon Masque Jun 01 '18 at 04:13
  • Possible duplicate of [Removing Item From List - during iteration - what's wrong with this idiom?](https://stackoverflow.com/questions/2896752/removing-item-from-list-during-iteration-whats-wrong-with-this-idiom) – Reblochon Masque Jun 01 '18 at 04:15
  • As @ReblochonMasque says; when you remove an item from `ordered_list`, it's now shorter, but you are using as many indices as the original list length, so you're going to try to access an item that's not there anymore. Just create a new list to return. Either way this could be done in a one-liner, without a function. `my_new_list = [item for item in my_list if item not in temp]`. – alkasm Jun 01 '18 at 04:16
  • But it could be done faster than this quadratic time algorithm by using a dictionary or set instead. – alkasm Jun 01 '18 at 04:16

4 Answers4

7

You actually can remove items from a list while iterating over it but do read links by @ReblochonMasque.

Here is one way of removing duplicates:

def remove_items_from_list(ordered_list, temp):
    n = len(ordered_list)
    for i in range(n - 1, -1, -1):
        if ordered_list[i] in temp:
            del ordered_list[i]      

Then

>>> remove_items_from_list(my_list, temp)
>>> print(my_list)
[2, 3, 4]

However, one of the easiest ways of solving your problem is to use sets:

list(set(my_list) - set(temp))

When using this approach, order of items in the resulting list may be arbitrary. Also, this will create a new list instead of modifying an existing list object. If order is important - use list comprehension:

[v for v in my_list if v not in temp]
AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
  • `set()` will remove duplicates and changes list order, if my_list is `[1,1]` and temp is `[1]`, it returns `None`, but it suppose to return `[1]` – letmecheck Jun 01 '18 at 09:09
2

While you iterating your loop, you remove item from orderer_list which cause index error Try this:

def remove_items_from_list(ordered_list, temp):
    list_ = [x for x in orderer_list if x not in temp]
    return list_
jerrycheng
  • 167
  • 8
0

first find the duplicated elements and then remove them from the original list.

dup_list = [item for item in temp if item in my_list]

for ele in dup_list:
    my_list.remove(ele)

remove() source

letmecheck
  • 1,183
  • 8
  • 17
-1

You can't remove an items from the list you are iterating over. You can create a copy of the array and remove items from it.