1

I expect the output of the following code

def unique_in_order(iterable):
    new = []
    for letter in iterable:
        new.append(letter)
    n = len(new)
    for i in range(n):
        if new[i] == new[i+1]:
            new.pop(i)
    return new

print(unique_in_order('AAAABBBCCDAABBB'))

to be ['A','B','C','D','A','B']

Why do I get the "list index out of range" error?

Heikki
  • 2,214
  • 19
  • 34
Vinamra
  • 11
  • 2
  • so if i replace n with n - 1 still no working – Vinamra Oct 28 '20 at 17:40
  • could you tag this question with the language you are using? – Michael Welch Oct 29 '20 at 00:22
  • Your problem is [related to this](https://stackoverflow.com/q/6260089/8881141). tl;dr: Don't modify lists like `new` while iterating over them. You can't change motor parts of a running car (well, you can, but don't complain when you end up in hospital). – Mr. T Oct 29 '20 at 13:20

3 Answers3

2
def unique_in_order(iterable):
    new = []
    for letter in iterable:
        new.append(letter)
    n = len(new)
    for i in range(n): # <-- [2]
        if new[i] == new[i+1]:
            new.pop(i) # <-- [1]
    return new

In line [1] you are removing elements from your list but you are still iterating over the full range (n= number of elements before you removed anything) [2].

You could

  • check if i is still smaller than the length of your list,
  • replace your loop with a while loop and account for the missing indizes or
  • look at the snippet @Suraj Subramanian provided.
sneusse
  • 1,422
  • 1
  • 10
  • 18
0

Try this.

def unique_in_order(iterable):
    ans = [iterable[0]]
    for i in range(1, len(iterable)):
        if iterable[i] != iterable[i-1]:
            ans.append(iterable[i])
    return ans
    
print(unique_in_order('AAAABBBCCDAABBB')) # prints ['A', 'B', 'C', 'D', 'A', 'B']
Suraj
  • 2,253
  • 3
  • 17
  • 48
0

A while loop can be used instead of for loop. And we could check the length of list every time we remove one element.

def unique_in_order(iterable):
    new = []
    for letter in iterable:
        new.append(letter)
    n = 0
    i = 0
    n = len(new)
    while i < n - 1: # iteration should be always smaller than length of list.
        if new[i] == new[i+1]:
            new.pop(i+1)
            n = len(new)
        else:
            i = i + 1
    return new

print(unique_in_order('AAAABBBCCDAABBB'))
Enis Arik
  • 665
  • 10
  • 24