Home > Back-end >  How to remove all before for empty list?
How to remove all before for empty list?

Time:07-02

Can not figure out how to produce the result with function:

remove_all_before([],0) == []

I tried using bool(), len(), and if not, but nothing worked for me

from typing import Iterable


def remove_all_before(items: list, border: int) -> Iterable:
    for x in list(items):
        if items:
            if items.count(border)>0:
                if x == border:
                    return(items)
                else:
                    items.remove(x)
            else:
                return(items)
        else:
            return(items)

CodePudding user response:

This is what I'm thinking, since the border is an int but not the index of the list, using the index() method of the give list to mark where to slice the whole list (as I've said in my preliminary comment) . It would of course find the first element in the list and include all the repetions of 4.

>>> def remove_all_before(items, border):
...     return items[items.index(border)::]
...
>>> a_list = [3, 4, 5, 1, 2, 4]
>>> remove_all_before(a_list, 1)
[1, 2, 4]
>>> remove_all_before(a_list, 4)
[4, 5, 1, 2, 4]
>>> remove_all_before(a_list, 2)
[2, 4]

EDIT:

Thanks for awarding me, @AlbertWijaya , you are too kind. But I think the other solution with the if border in items: ...; else: ... by @Wonka is more complete.

It's exactly what I was proposing from my comment with the condition in case the border is not inside the list. I cannot be sure cause I didn't check, but it probably was posted even before my answer

CodePudding user response:

With default return of complete list, if element border not in list:

def remove_all_before(input_list, input_border):
    if input_border in input_list:
        return input_list[input_list.index(input_border):]
    else:
        return input_list  # return entire list if border not contained

remove_all_before([1,2,3,4,5], 3)

Prints: [3, 4, 5]

CodePudding user response:

To complex code with nested if-statements and obsolete list-construction, duplicated return branches.

Hard to spot a logical bug, so I would clean first:

Clean the code first

def remove_all_before(items: list, border: int) -> Iterable:
    for x in list(items):  # no need to construct a list from list
        if items:  # 1st condition (use and)
            if items.count(border)>0:  # 2nd condition (use and)
                if x == border:   # 3rd condition (use and, flip to remove as consequence)
                    return(items)  # remove the default branch (duplicate 1 of 3)
                else:
                    items.remove(x)
            else:
                return(items)  # remove the default branch (duplicate 2 of 3)
        else:
            return(items)  # un-indent (without else) as default return (duplicate 3 of 3)

Then spot the issue

def remove_all_before(items: list, border: int) -> Iterable:
    for x in items:  # items is a list already, no need for list()
        if items and items.count(border) > 0 and x != border:  # combined nested if-conditions to one (with a little flip)
            items.remove(x)
return items  # return default (duplicates removed)

Considerations:

  • Shouldn't it stop removing, one before x == border reached ?
  • Shouldn't it return immediately, once x == border is met ?
  • Instead items and items.count(border) > 0 you can also use border in items to test if the list contains the border (and thus is non-empty)
  • If border is not in list at all, you don't need to loop and remove, do you?
  • Wouldn't a while loop be suitable to iterate and remove until the element border is found ?
  • Related