-2

I want to remove duplicates from a list. I know it can be done easily with list(dict.fromkeys(my list)), but I want to do it by iterating through the list. When I am removing a duplicate number from the list, the loop variable j causes an Index error : list index out of range later in subsequent iterations, even though I am changing the range input. I am wondering how to change loop variable inside loop ?

def rem_duplicate(seq):
    for i in range(len(seq)):
        num = seq[i]
        count = 0
        length = len(seq)
        for j in range(length):
            if seq[j] == num:
                count += 1
                if count > 1:
                    del seq[j]
                    length=length-1
    return seq

my_list = [2, 3, 4, 5, 6, 7, 8, 3, 4, 1, 5, 2, 5, 7, 9]

print(rem_duplicate(my_list))
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • Especially this answer: https://stackoverflow.com/a/42773232/895932 that uses a while loop. – justhalf Oct 13 '20 at 06:08
  • you could directly use set(my_list) or for iteration you could use while loop instead – Anurag Singh Oct 13 '20 at 06:08
  • Your changing of `length` variable inside the `for` loop does nothing. The loop has already been initialised with the original value of length and the value won't be updated. – NotAName Oct 13 '20 at 06:08
  • 1
    also mutating a list like this while iterating through it is a nightmare, the moment you delete an element your loop counter becomes incorrect, a better way is to filter out the elements you don't want and to accumulate in another list using a list comprehension as linked to above. – fibonachoceres Oct 13 '20 at 06:08
  • List comprehension cannot be used to delete duplicates since it cannot access other elements, so I suggested an answer in that duplicate target question that uses a while loop, which is applicable in this case. – justhalf Oct 13 '20 at 06:10

2 Answers2

2

When you enter the inner loop, the range() function is called with current value of length, say, 3. So, your loop would look like for j in [1, 2, 3] and changing length won't affect changing the mentioned list.

To achieve what you want, and also when mutating the size of the list you're iterating on, it's always better to use a while loop:

j = 0
while j < length:
  if seq[j] == num:
    count += 1
    if count > 1:
      del seq[j]
      length=length-1
  j += 1
Ali Tou
  • 2,009
  • 2
  • 18
  • 33
0

range(len(seq))

Will return an inmutable sequence, that will not be affected by add / del operations over the original list. Take a look to the previous answers to the same question (using a while): Python: remove duplicate items from a list while iterating