有没有一种优雅的pythonic方法可以从列表中删除末尾的空元素?一种类似于list.rstrip(None)
的方式。
[1, 2, 3, None, 4, None, None]
应该导致
[1, 2, 3, None, 4]
我猜这可以泛化为删除任何特定值的尾随元素。
如果可能的话,我希望将其作为单行(可读)表达式完成。
如果您想排除只有 None
值并保留零或其他假值,可以执行以下操作:
while my_list and my_list[-1] is None:
my_list.pop()
要删除所有假值(零、空字符串、空列表等),可以执行以下操作:
my_list = [1, 2, 3, None, 4, None, None]
while not my_list[-1]:
my_list.pop()
print(my_list)
# [1, 2, 3, None, 4]
None
元素:while l and l[-1] is None:
l.pop()
f = lambda x: x is None
while l and f(l[-1]):
l.pop()
现在您可以定义不同的功能来检查其他条件。
def remove_trailing(l, remove_value=None):
i = len(l)
while i > 0 and l[i - 1] == remove_value:
i -= 1
return l[:i]
l
参数吗?而不是返回它?(肯定不是那样) - alanreturn l[:i]
,而是使用l[:] = l[:i]
。这样做会将其变成一个命令,因为它会改变l
的状态。我之前的想法是错误的,因为它目前是一个查询(返回数据且不改变状态),所以它确实保留了命令查询分离。我原本想像这样使用它:l = remove_trailing(l)
,但那样会违反CQ分离,我认为这样做有点过于拘泥小节了。 - aaronasterling试试这个
>>> x=[1, 2, 3, None, 4, None, None]
>>> while x[-1] is None:
x.pop()
一行代码解决方案:
In [30]: from itertools import dropwhile
In [31]: list(reversed(tuple(dropwhile(lambda x: x is None, reversed([1, 2, 3, None, 4, None, None])))))
Out[31]: [1, 2, 3, None, 4]
如果你想重复使用它,在这里是一个无点风格的定义:
In [36]: from functional import compose, partial
In [37]: varargs = lambda *args: args
In [38]: compose_mult = compose(partial(reduce, compose),varargs) # compose which takes variable number of arguments. Innermost function to the right.
In [39]: compose_mult(list, reversed, tuple, partial(dropwhile, lambda x: x is None), reversed)([1, 2, 3, None, 4, None, None])
Out[39]: [1, 2, 3, None, 4]
a = [1, 2, None, 3, None, None]
reduce(lambda l, e: [e]+l if l or e is not None else [], reversed(a), [])
a = [1, 2, 3, None, 4, None, None]
b = [x for n, x in enumerate(a) if any(y is not None for y in a[n:])]
print b
b = [x for n, x in enumerate(a) if any(a[n:])]
如果你真的需要牺牲可读性,这是我会做的。
>>> from itertools import takewhile
>>> l=[1,2,3,None,4,5,None,None]
>>> l[:-len(list(takewhile(lambda x: x==None, reversed(l))))]
[1,2,3,None,4,5]
more_itertools
项目为任何可迭代对象实现了 rstrip
方法:
iterable = [1, 2, 3, None, 4, None, None]
list(mit.rstrip(iterable, lambda x: x in {None}))
# [1, 2, 3, None, 4]
more_itertools.rstrip
接受一个可迭代对象和谓词。有关详细信息,请参见源代码。
这个怎么样:
[a[i] for i in range(len(a)) if a[i:] != [None] * (len(a) - i) ]
[None]
,[None, None]
,[0, '', []]
等。另一个答案 解决了这个问题。 - Georgy