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 useborder in items
to test if the list contains theborder
(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 elementborder
is found ?