简体   繁体   中英

How to remove all before for empty list?

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)

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]

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: ... 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

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 ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM