0

I'm trying to solve a little puzzle, where I need to delete the number 13, and the number after that in a list (its an exercise on CodingBat).

This is my code:

n = [1, 2, 3, 13, 5, 13] 

for i in n:
    if i == 13:
        n.remove(i) and n.remove(n.index(i+1))

print n

Desired output: [1, 2, 3]

However, my incorrect output is: [1, 2, 3, 5] #the item after 13 (i.e. 5) did not get deleted

I thought that this n.remove(n.index(i+1)) would remove the item after 13, but it doesn't.

apples-oranges
  • 959
  • 2
  • 9
  • 21
  • 3
    After you remove `13`, what's the index of `5`? Don't change the length of a list while iterating over it. – jonrsharpe Jun 28 '16 at 19:29
  • 1
    `n.index(x)` is defined as "Return the smallest `i` such that `i` is the index of the first occurrence of `x` in the array." – Eli Sadoff Jun 28 '16 at 19:29
  • 2
    Your use of the `and` keyword is wrong. You cannot string together commands on a single line using it. `and` is a replacement for the logical operator `&&`, so youre trying to compare two none returning operations instead of executing two – m_callens Jun 28 '16 at 19:31
  • 2
    @m_callens he is also mixing his use of `i` as an iterated value and index – Assimilater Jun 28 '16 at 19:32
  • @Assimilater yep I just noticed that as well! – m_callens Jun 28 '16 at 19:33
  • @m_callens Could you explain this a bit more, mixing `i` – apples-oranges Jun 28 '16 at 19:40
  • 2
    @m_callens actually that will work just fine although it's considered a bit of a hack. – jonrsharpe Jun 28 '16 at 19:45
  • @jonrsharpe what will – m_callens Jun 28 '16 at 19:48
  • @m_callens ...the thing you said was wrong. Chaining two operations with `and`. It's lazily evaluated, so the second half won't happen if the first half returns a falsy value. – jonrsharpe Jun 28 '16 at 19:49
  • 1
    @jonrsharpe yes I understand that the FIRST will always execute, but I don't think that was on purpose....syntactically correct, semantically wrong – m_callens Jun 28 '16 at 19:50
  • 1
    @apples-oranges The issue with the way that you're using `i` is that you're using it as an `iterator` AND an `indexer` in the same situation. When you do `for i in n`... `i` "becomes" each value within the list `(i.e. 1, 2, 3, 13, 5, 15)`, so when you do `n.index(i + 1)`, you're trying to find the index of `14` when `i = 13` and `14` is not in the list – m_callens Jun 28 '16 at 19:53
  • @m_callens Ah yes of course! Thanks! – apples-oranges Jun 28 '16 at 20:04
  • 1
    `new_n = [n[i] for i,x in enumerate(n) if not 13 in n[max(0,i-1):i+1]]` – ml-moron Jun 28 '16 at 20:44
  • @K.Menyah nice one liner :-) – apples-oranges Jun 28 '16 at 20:49

2 Answers2

2

This should work:

n = [1, 2, 3, 13, 5, 13] 

for i in n:
    if i == 13:
        n.remove(n[n.index(i)+1]) # remove the element after `i` first
        n.remove(i) 

print n

A while loop for the problem:

n = [1, 2, 3, 13, 5, 13] 

i = 0
while i < len(n):
    if n[i] == 13:
        n.pop(i)
        if i < len(n):
            n.pop(i)
    else:
        i = i + 1

print n

# [1, 2, 3]
Psidom
  • 209,562
  • 33
  • 339
  • 356
0

After your n.remove(), your array is [1, 2, 3, 5, 13] so the n.remove(n.index(i+1)) refers to 13 not to 5