Python has a string method called rstrip()
:
>>> s = "hello world!!!"
>>> s.rstrip("!")
'hello world'
I want to implement similar functionality for a Python list. That is, I want to remove all instances of a given value from the end of a list. In this case, the value is None
.
Here's some starting examples:
[1, 2, 3, None]
[1, 2, 3, None, None, None]
[1, 2, 3, None, 4, 5]
[1, 2, 3, None, None, 4, 5, None, None]
I want the end results to be:
[1, 2, 3]
[1, 2, 3]
[1, 2, 3, None, 4, 5]
[1, 2, 3, None, None, 4, 5]
Here's my solution so far:
while l[-1] is None:
l.pop()
CodePudding user response:
If you want to modify the list in-place, then your solution is good, just make sure you handle the case when the list is empty:
while l and l[-1] is None:
l.pop()
If you want to compute a new list, you can adapt your solution into:
def stripNone(l):
if not l:
return []
rlim = 0
for x in reversed(l):
if x is None:
rlim = 1
else:
break
return l[: len(l) - rlim]
There is also itertools.dropwhile
, but you have to perform two reversals:
def stripNone(l):
return list(dropwhile(lambda x: x is None, l[::-1]))[::-1]
CodePudding user response:
Two more versions that also work for None
-only lists:
while None in l[-1:]:
l.pop()
for x in reversed(l):
if x is not None:
break
l.pop()
Benchmarking some solutions on l = [None] * 10**6
:
82 ms stripNone1
136 ms stripNone2
60 ms stripNone3
42 ms stripNone3b
55 ms stripNone4
Benchmark code:
from timeit import repeat
def stripNone1(l):
while l and l[-1] is None:
l.pop()
def stripNone2(l):
while None in l[-1:]:
l.pop()
def stripNone3(l):
for x in reversed(l):
if x is not None:
break
l.pop()
def stripNone3b(l):
pop = l.pop
for x in reversed(l):
if x is not None:
break
pop()
def stripNone4(l):
for i, x in enumerate(reversed(l), 1):
if x is not None:
del l[-i:]
break
solutions = stripNone1, stripNone2, stripNone3, stripNone3b, stripNone4
for i in range(3):
print(f'Round {i 1}:')
for sol in solutions:
ls = [[None] * 10**6 for _ in range(5)]
time = min(repeat(lambda: sol(ls.pop()), number=1))
print(f'{int(time * 1000):3d} ms {sol.__name__}')