python中的buildin strip
方法可以轻松剥离满足自定义条件的填充子字符串。例如
"000011110001111000".strip("0")
将在字符串的两侧修剪零填充,并返回11110001111
。
我想为列表找到类似的功能。例如,对于给定列表
input = ["0", "0", "1", "1", "0", "0", "1", "0", "1", "0", "0", "0"]
预期输出将为
output = ["1", "1", "0", "0", "1", "0", "1"]
示例input
中的项目过于简化,它们可能是任何其他python对象。
list comprehension
将删除所有项目,而不是填充项目。
[i for i in input if i != "0"]
答案 0 :(得分:5)
从两端使用itertools.dropwhile
:
from itertools import dropwhile
input_data = ["0", "0", "1", "1", "0", "0", "1", "0", "1", "0", "0", "0"]
def predicate(x):
return x == '0'
result = list(dropwhile(predicate, list(dropwhile(predicate, input_data))[::-1]))[::-1]
result
输出:
['1', '1', '0', '0', '1', '0', '1']
答案 1 :(得分:2)
没有列表方法,但是实现这样的功能并不困难:扫描所需的索引,然后切片到它们。
def strip_seq(predicate, xs):
def scan(xs):
return next((i for i, x in enumerate(xs) if not predicate(x)), 0)
return xs[scan(xs) : -scan(reversed(xs)) or None]
xs = ["0", "0", "a", "1", "0", "0", "1", "0", "b", "0", "0", "0"]
print(strip_seq(lambda x: x=='0', xs)) # ['a', '1', '0', '0', '1', '0', 'b']
这应该适用于任何可切片的序列类型,包括字符串和元组。
答案 2 :(得分:1)
您可以右键单击while / pop。
input = ["0", "0", "1", "1", "0", "0", "1", "0", "1", "0", "0", "0"]
while input and input[-1] == "0": input.pop()
您可以使用itertools.dropwhile
左移,但是您可能必须重新创建一个列表。
from itertools import dropwhile
input = [*dropwhile(lambda x: x=='0', input)]
或者您可以通过转换为双端队列从两端高效地进行while / pop操作。
from collections import deque
input = ["0", "0", "1", "1", "0", "0", "1", "0", "1", "0", "0", "0"]
input = deque(input)
while input and input[-1] == '0': input.pop()
while input and input[0] == '0': input.popleft()
(而且input()
已经是一个内置函数,因此最好不要将该名称重复用于变量。)
答案 3 :(得分:0)
没有内置方法。您可以使用itertools.dropwhile
左移。可以使用生成器功能进行剥离。
import itertools as it
stripleft = list(it.dropwhile(lambda x: x==myitem, inputlist))
答案 4 :(得分:0)
下面给出“基本”解决方案。使用dropwhile的解决方案会反转输入,这在某些情况下可能会很昂贵。
下面的解决方案计算开始和结束索引并返回输入的一部分。
此解决方案适用于其他类型的序列,例如元组,其返回值与输入的类型相同。尽管str.split()
可能会更快,但该方法也适用于字符串输入。
def strip_basic(input_data, predicate):
N = len(input_data)
if not N:
return input_data[0:0] # empty sequence, new copy for mutables
i = 0
while i < N and predicate(input_data[i]):
i = i + 1
if i == N: # optimization
return input_data[0:0] # empty sequence
j = N - 1
while j and predicate(input_data[j]):
j = j - 1
j = j + 1
return input_data[i:j]
为进行比较(在此解决方案中,一部分输入被反向两次):
def strip_dropwhile(input_data, predicate):
return list(dropwhile(predicate, list(dropwhile(predicate, input_data))[::-1]))[::-1]
以下是一些使用timeit
的数字。请注意,对于病理情况,输入很大,并且没有要输入的元素
去除掉,dropdrop解决方案比基本解决方案慢大约8倍。
在输入较大且所有元素都被剥离的情况下,基本解决方案是
比dropdrop解决方案慢1.9倍。
# input len = 12, output len = 7
# predicate = lambda x: x == '0'; input_data = list('001100101000')
# dropwhile solution:
200000 loops, best of 5: 1.84 usec per loop
# basic solution:
200000 loops, best of 5: 1.51 usec per loop
# input len = 1,000,000, output len = 1,000,000
# predicate = lambda x: x == '0'; input_data = ['1'] * 1000000
# dropwhile solution:
10 loops, best of 5: 29.3 msec per loop
# basic solution:
100 loops, best of 5: 3.58 msec per loop
# input len = 1,000,000, output len = 0
# predicate = lambda x: x == '0'; input_data = ['0'] * 1000000
# dropwhile solution:
5 loops, best of 5: 98 msec per loop
# basic solution:
2 loops, best of 5: 183 msec per loop