Home > Net >  Which is more efficient, more code or more conditional checks?
Which is more efficient, more code or more conditional checks?

Time:04-03

I am doing the 7th exercise on 10 Algorithms To Solve Before your Python Coding Interview. It is about moving the zeroes of a list to the end. I thought of writing a function that moves those zeroes to the end or start based on a boolean argument.

def move_zeroes(numbers, to_start = False):
    pass

The idea in my mind for the move-to-end case was this.

def move_zeroes(numbers):
    for i in numbers:
        if i == 0:
            numbers.remove(i)
            numbers.append(i)

Extending this, I came across two choices.

More code, less conditional checks

def move_zeroes(numbers, to_start = False):
    if to_start:
        for i in numbers:
            if i == 0:
                numbers.remove(i)
                numbers.insert(0, i)
    else:
        for i in numbers:
            if i == 0:
                numbers.remove(i)
                numbers.append(i)

Less code, more conditional checks

def move_zeroes(numbers, to_start = False):
    for i in numbers:
        if i == 0:
            numbers.remove(i)
            numbers.insert(0, i) if to_start else numbers.append(i)

Does there exist a way between these? Can I have less code and less conditional checks? Also, how does this scale for larger lengths of lists?

As a secondary question, in case this is not possible, what is the practical way to do this particular example, keeping in mind memory and extra lines? In other words, which of the two tradeoffs is better than the other?

EDIT 1: Rename list parameter to numbers on the suggestion of @aaossa.

CodePudding user response:

Continually calling remove() (notwithstanding the fact that you shouldn't do that on a list that you're currently iterating over) could be very inefficient as the list has to be scanned from its first element until such time as the remove criterion has been matched.

I propose this:

alist = [1,0,0,2,0,3,0,4,0,5]

def move_zeroes(lst):
    # build a list from all the non-zero elements of the input list
    newlist = list(filter(None, lst))
    # the difference in the lengths of the original and new list
    # will be the number of zeroes that were not copied
    nz = len(lst) - len(newlist)
    # now extend the new list with a list of zeroes of appropriate
    # length and copy into the address space of the given parameter
    lst[:] = newlist   [0] * nz

move_zeroes(alist)

print(alist)

Output:

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

CodePudding user response:

list2 = [1, 0, 0, 2, 0, 3, 0, 4, 0, 5]
temp = 0
for i in range(len(list2)):
    for k in range(i 1, len(list2)):
        if list2[i] == 0 and list2[i] < list2[k]:
            temp = list2[i]
            list2[i] = list2[k]
            list2[k] = temp

print(list2)

  • Related