0

I'm doing a coding problem where the aim is to "write a function that takes an array of values and moves all elements that are zero to the end of the array, otherwise preserving the order of the array. The zero elements must also maintain the order in which they occurred."

I'm testing my code in Python, and running into a problem where I'm setting a condition to ignore 0's when I find them, but the condition is not working. Is it because I'm modifying the list in the loop, and it is not considering the updated values? Can I handle this without extra space?

def remove_zeros(array):
    for i in range(len(array)):
        if array[i] != 0 or array[i] != "0":
            c = array[i]
            print(c) #this is printing 0, but I'm setting condition to ignore 0's!
            for j in range(i, 0, -1):
                if array[j - 1] == 0 or array[j - 1] == "0":
                    temp = array[j]
                    array[j] = array[j - 1]
                    array[j - 1] = temp
    return array

input = [ 1, None, '5', '0', '2', 0, 8, 6, None, False ]
output = remove_zeros(input)
Perplexityy
  • 561
  • 1
  • 9
  • 26
  • instead of having the inner for loop, you can pop and append the element to preserve the state. – gnahum May 11 '20 at 06:09
  • Or have two counters and one for the current element and the other for how many zeros removed. I'll add in both as an answer. – gnahum May 11 '20 at 06:11
  • well you can do it in two diffrent ways, the first is to count each zero you find and remove it from the array, (then at the end) append them at the array end or the second solution is, moving each zero you find while iterating to the end and close the gap by shifting backwards. i will commit my answer. it looks to me that you are looking for solution 2. – Adam May 11 '20 at 06:14

4 Answers4

1

Preface

We can do this problem in multiple ways.

Method 1: pop/append

This method simply pops the current element and appends it to the end. This method ensures it is the same type.

def remove_zeros(arr): 
    n = len(arr): 
    for i in range(n): 
        if arr[i] == 0 or arr[i] == '0': 
             # this will be a zero. 
             arr.append(arr.pop(i)) # remove and add it to the end. 
    return arr 

Method 2: Count the number of zeros and override it.

This method assumes you can return any type of zero.

def remove_zeros(arr): 
    n = len(arr) 
    counter = 0 
    for i in range(n):
        if arr[i] != 0 and arr[i] != '0': 
           arr[counter] = arr[i] 
           counter += 1 
    while counter < n:  
        arr.append(0)
        counter += 1 
    return arr 
gnahum
  • 426
  • 1
  • 5
  • 13
  • I am not looking for help with the logic of the question, I am asking why my code is still printing 0's despite my if condition. – Perplexityy May 11 '20 at 06:43
  • Sorry for misunderstanding your question. Your logic is if it doesn't equal int(0) or string(0). Suppose you have a string "0" then arr[I] won't be equal to int(0) therefore it will be true and the body of the if will be executed. I believe you need to modify it to an "and" rather than "or" – gnahum May 11 '20 at 16:41
0

nevermind, I had to change the or condition to an and

Perplexityy
  • 561
  • 1
  • 9
  • 26
0

You can harness sorted for that task following way:

ipt = [1, None, '5', '0', '2', 0, 8, 6, None, False]
opt = sorted(ipt, key=lambda x:x is 0 or x=='0')
print(opt)  # [1, None, '5', '2', 8, 6, None, False, '0', 0]

Note that this is possible thanks to two facts: sorted is stable and False is treated as 0, True as 1, if such need arise, thus all elements which were marked False by supplied function go to begin and True go to end, as 0 < 1. Note that I used is rather than == as False == 0 evaluates to True, whilst False is 0 does not.

Daweo
  • 31,313
  • 3
  • 12
  • 25
-1

To remove items from a list use the built-in "filter" function. For example,

def remove_zero(item):
    return item is not 0 and item!='0'

input  = [ 1, None, '5', '0', '2', 0, 8, 6, None, False ]
output = list(filter(remove_zero, input))
Bobby Ocean
  • 3,120
  • 1
  • 8
  • 15