0

I did one simple code to separate elements of an array into two new arrays : one with odd numbers and other with even numbers. So I did this:

V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
   if x%2==0:
      vp.append(x)
      V.remove(x)
   else:
      vi.append(x)
      V.remove(x)

print (V)
print (vp)
print (vi) # sorry for the bad identation first time sharing code here

and this code give me this result:

[2,4,6]
[]
[1,3,5]

How is it happen? How am I fix this?

Crispin
  • 2,070
  • 1
  • 13
  • 16
  • 2
    What is your expected/desired output, precisely? – ShadowRanger Mar 07 '17 at 03:24
  • Your indentation looks fine, but your comment is invalid Python--it should start with `#` not `//`. – KernelPanic Mar 07 '17 at 03:25
  • 3
    When you are iterating through a list with python, removing an item from that list will cause you to skip an item. In this case you are iterating through V. So you end up modifying your list like so: V[0] == 1 V[1]==2 V[2]==3 V.remove(0) V[0]==2 V[1]==3 – SuperTetelman Mar 07 '17 at 03:25

6 Answers6

0

Don't remove items from a list over which you are iterating. Use a copy:

V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V[:]:
   if x%2==0:
      vp.append(x)
      V.remove(x)
   else:
      vi.append(x)
      V.remove(x)

print (V)
print (vp)
print (vi)
# []
# [2, 4, 6]
# [1, 3, 5]
Crispin
  • 2,070
  • 1
  • 13
  • 16
0

You shouldn't remove item while traversing an array:

V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
 if x%2==0:
   vp.append(x)
 else:
  vi.append(x)
Luong Dinh
  • 569
  • 4
  • 17
0

Modifying a list mid-iteration causes misbehavior (you effectively skip input elements). Don't remove from V as you go (which for long V would be expensive, each remove is O(n) making total work O(n**2)), just leave V unmodified. If necessary, clear V when you finish (a single O(n) operation), e.g. after the loop:

del V[:]
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

When you remove items from a list, the list gets shorter. So when you're looping over a list in a forward direction, removing items will cause the the iterator to skip forward.

To mitigate this, you can loop backwards over a list and safely remove items, since you're removing them from the end.

V = [1,2,3,4,5,6]
vp = []
vi = []

# reverse the list before iterating
for x in reversed(V):
    if x % 2 == 0:
        vp.append(x)
        V.remove(x)
   else:
        vi.append(x)
        V.remove(x)
Soviut
  • 88,194
  • 49
  • 192
  • 260
0

Other answers that identified the problem and the fix, but here is a different way to do it using list comprehensions.

numbers = [1,2,3,4,5,6]
even = [e for e in numbers if e % 2 == 0]
odd = [e for e in numbers if e % 2 == 1]
Hesham Attia
  • 979
  • 8
  • 13
0

A more concise way to make a new odd and even list from the original is to use comprehensions:

v = [1,2,3,4,5,6]
even = [number for number in v if number % 2 == 0]
odd = [number for number in v if number % 2 != 0]
Chase G.
  • 113
  • 5