0

I was hoping someone would be able to help me out with this too. I am trying to solve the same problem, though I am trying to use a for loop & python built in functions as you will see below.

def move_zeros(lst):
    new_ls = []
    for i in lst:
        if i == 0:
            new_ls.append(i)
            lst.remove(i)
    return (lst)

samp_lis = [9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]
print(move_zeros(samp_lis))

However, for what ever reason the for loop only makes it way to index 13 before it concludes. Could someone explain to me why it does this? No matter what I do I can't seem to make the for loop keep going

[9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]

Below is the answer I keep getting

[9, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]

The same answer has been asked before, however, it looks like everyone took a sorting approach. I wanted to know if it was possible to do this with a for loop.

Previous Question: Move all zeros to the end of the array in python

InSync
  • 4,851
  • 4
  • 8
  • 30
Christian
  • 9
  • 3

4 Answers4

0

The problem is lst.remove(i) which has two problems: It moves the remaining list up one, effectively skipping the next value, and it removes the first occurance of the value, not the one you are looking at. If that skipped value happened to be a 0, a future 0 value would remove the first one, not the current one. So, you skip values and seemingly remove other zeroes randomly.

remove is a relatively expensive operation because the remaining list needs to be shifted. You might as well create a couple of lists and add them on return.

def move_zeros(lst):
    return [val for val in lst if val != 0] + [val for val in lst if val == 0]

That's a for loop in the list comprehension. But if that doesn't count, you could remove values from back to front, eliminating the problem of the changing list. You can enumerate the list backwards and delete by index, adjusting for negative indexing starts from -1, not 0.

def move_zeros(lst):
    for i, val in enumerate(reversed(lst), 1):
        if val == 0:
            del lst[-i]
            lst.append(0)
    return lst
tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

i think the problem is that you are trying to loop through a list and edit it in the same time , this code produces the desierd output

def move_zeros(lst):
    new_ls = []
    for i in lst:
        if i != 0:
            new_ls.append(i)
    return (new_ls)

samp_lis = [9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]
print(move_zeros(samp_lis))
0

If you specifically wanted to loop over the list and modify it in-place (which is effectively doing a sort, even if you aren't using the built-in sort function), this might be one way to approach it (note that this isn't "stable", in that the order of the non-zero elements isn't preserved):

def move_zeros(nums):
    end = len(nums) - 1
    for i in range(len(nums)):
        if nums[i]:
            continue
        # Find the last non-zero element to swap with
        while nums[end] == 0:
            end -= 1
        if end <= i:
            break  # we swapped all the zeros, all done!
        nums[i], nums[end] = nums[end], nums[i]

samp_lis = [9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]
move_zeros(samp_lis)
print(samp_lis)
# [9, 9, 9, 9, 1, 2, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

But I would tend to agree that it's much easier to do something like:

def move_zeros(nums):
    return [n for n in nums if n] + [n for n in nums if not n]

samp_lis = [9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]
print(move_zeros(samp_lis))
# [9, 9, 1, 2, 1, 1, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Samwise
  • 68,105
  • 3
  • 30
  • 44
-1
values = [9, 0, 0, 9, 1, 2, 0, 1, 0, 1, 0, 3, 0, 1, 9, 0, 0, 0, 0, 9]
end_index = len(values) - 1
for i in values:
    if i == 0:
        val_index = values.index(i)
        while val_index != end_index:
            values[val_index], values[val_index + 1] = values[val_index + 1], values[val_index]
            val_index += 1

print(values)

>>> [9, 9, 1, 2, 1, 1, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
tushortz
  • 3,697
  • 2
  • 18
  • 31