3

Problem

Link to the problem: https://www.codewars.com/kata/52597aa56021e91c93000cb0/train/python

Write an algorithm that takes an array and moves all of the zeros to the end, preserving the order of the other elements.

move_zeros([false,1,0,1,2,0,1,3,"a"]) # returns[false,1,1,2,1,3,"a",0,0]

My code:

def move_zeros(array):
    zero_count = array.count(0)
    array1 = list(filter(lambda a: a != 0, array)) + [0 for i in range(zero_count)]
    return array1

Sample Tests:

Test.describe("Basic tests")
Test.assert_equals(move_zeros([1,2,0,1,0,1,0,3,0,1]),[ 1, 2, 1, 1, 3, 1, 0, 0, 0, 0 ])
Test.assert_equals(move_zeros([9,0.0,0,9,1,2,0,1,0,1,0.0,3,0,1,9,0,0,0,0,9]),[9,9,1,2,1,1,3,1,9,9,0,0,0,0,0,0,0,0,0,0])
Test.assert_equals(move_zeros(["a",0,0,"b","c","d",0,1,0,1,0,3,0,1,9,0,0,0,0,9]),["a","b","c","d",1,1,3,1,9,9,0,0,0,0,0,0,0,0,0,0])
Test.assert_equals(move_zeros(["a",0,0,"b",None,"c","d",0,1,False,0,1,0,3,[],0,1,9,0,0,{},0,0,9]),["a","b",None,"c","d",1,False,1,3,[],1,9,{},9,0,0,0,0,0,0,0,0,0,0])
Test.assert_equals(move_zeros([0,1,None,2,False,1,0]),[1,None,2,False,1,0,0])
Test.assert_equals(move_zeros(["a","b"]),["a","b"])
Test.assert_equals(move_zeros(["a"]),["a"])
Test.assert_equals(move_zeros([0,0]),[0,0])
Test.assert_equals(move_zeros([0]),[0])
Test.assert_equals(move_zeros([False]),[False])
Test.assert_equals(move_zeros([]),[])

My Output after running:

  • Test Passed

  • Test Passed

  • Test Passed

  • ['a', 'b', None, 'c', 'd', 1, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] should equal ['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

  • [1, None, 2, 1, 0, 0, 0] should equal [1, None, 2, False, 1, 0, 0]

  • Test Passed

  • Test Passed

  • Test Passed

  • Test Passed

  • Test Passed

  • Test Passed

My Question:

Why does my answer fail the 2 tests?

NewbieProgrammer
  • 157
  • 4
  • 11
  • Just swap in a loop, and keep track the last non-zero position. – Eric Apr 30 '20 at 12:24
  • @EricWang Thank you very much for the idea :) Please provide a solution with code. – NewbieProgrammer May 01 '20 at 08:09
  • Does this answer your question? [Moving Zeros To The End: Failing the test in CodeWars?](https://stackoverflow.com/questions/61661462/moving-zeros-to-the-end-failing-the-test-in-codewars) – anatolyg May 07 '20 at 16:55

5 Answers5

0

Because you just drop out all Falses in a != 0. False is 0 and 0 is False.

Further details: Is False == 0 and True == 1 an implementation detail or is it guaranteed by the language?

Psytho
  • 3,313
  • 2
  • 19
  • 27
0

In python, the values True and False behave as equivalent to 1 and 0 when compared to integers. See the section under numbers.Integral in the The standard type hierarchy. This means that when counting the zeroes, False will be counted as well, and in the lambda:

lambda a: a != 0

The comparison of a != 0 will filter out both 0 and False. One way to correct this is to modify the count to also be a filter, and to check in both lambdas that a is not a boolean:

def move_zeros(array):
    zero_list = list(filter(lambda a: a == 0 and not isinstance(a, bool), array))
    array1 = list(filter(lambda a: a != 0 or isinstance(a, bool), array)) + zero_list
    return array1
Lev Izraelit
  • 512
  • 4
  • 14
0

change all values a string and then perform the function

0

You need

def move_zeros(array):
    zero_count = array.count(0)
    array1 = list(filter(lambda a: a != 0 or isinstance(a, bool), array)) + [0 for i in range(zero_count)]
    return array1
Bhaskar
  • 1,838
  • 1
  • 16
  • 29
0

I found this answer and it works. I just don't understand how it works.

def move_zeros(a):
    a.sort(key=lambda v: v == 0)
    return a