python:从字符串列表中删除空字符串

我想从python中的字符串列表中删除所有空字符串。

我的想法是这样的:

1
2
while '' in str_list:
    str_list.remove('')

还有其他的python方法吗?


我将使用filter:

1
2
3
4
str_list = filter(None, str_list) # fastest
str_list = filter(bool, str_list) # fastest
str_list = filter(len, str_list)  # a bit slower
str_list = filter(lambda item: item, str_list) # slower than list comprehension

Python 3从filter返回一个迭代器,因此应该封装在对list()的调用中

1
str_list = list(filter(None, str_list)) # fastest

(等)

测试:

1
2
3
4
5
6
7
8
9
10
>>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.4797441959381104
>>> timeit('filter(bool, str_list)', 'str_list=["a"]*1000', number=100000)
2.4788150787353516
>>> timeit('filter(len, str_list)', 'str_list=["a"]*1000', number=100000)
5.2126238346099854
>>> timeit('[x for x in str_list if x]', 'str_list=["a"]*1000', number=100000)
13.354584932327271
>>> timeit('filter(lambda item: item, str_list)', 'str_list=["a"]*1000', number=100000)
17.427681922912598


列表理解

1
2
strings = ["first","","second"]
[x for x in strings if x]

输出:['first', 'second']

编辑:按建议缩短


filter实际上对此有一个特殊的选项:

1
filter(None, sequence)

它将过滤掉所有赋值为False的元素。这里不需要使用实际的可调用函数,比如bool、len等等。

它和map一样快(bool,…)


1
2
3
4
5
6
7
8
9
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']

>>> ' '.join(lstr).split()
['hello', 'world']

>>> filter(None, lstr)
['hello', ' ', 'world', ' ']

比较的时间

1
2
3
4
5
>>> from timeit import timeit
>>> timeit('"".join(lstr).split()',"lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
4.226747989654541
>>> timeit('filter(None, lstr)',"lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.0278358459472656

注意,filter(None, lstr)不删除带有空格' '的空字符串,它只删除'',而' '.join(lstr).split()删除两者。

要使用filter()删除空格字符串,需要花费更多的时间:

1
2
>>> timeit('filter(None, [l.replace("","") for l in lstr])',"lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635


为了消除空字符串,我将使用if x !="而不是if x !="是这样的:

1
str_list = [x for x in str_list if x != '']

这将在列表中不保留任何数据类型。此外,如果列表中有整数并且0是其中之一,那么它也将被保留。

例如,

1
2
3
str_list = [None, '', 0,"Hi", '',"Hello"]
[x for x in str_list if x != '']
[None, 0,"Hi","Hello"]


@Ib33X的回复很棒。如果要删除每个空字符串,请在删除后删除。你也需要使用条带法。否则,如果它有空格,它也将返回空字符串。比如,""也适用于这个答案。所以,可以通过。

1
2
strings = ["first","","second",""]
[x.strip() for x in strings if x.strip()]

答案将是["first","second"]
如果您想使用filter方法,您可以这样做
list(filter(lambda item: item.strip(), strings))。结果是一样的。


根据列表的大小,如果使用list.remove()而不是创建一个新列表,那么效率可能最高:

1
2
3
4
5
6
7
l = ["1","","3",""]

while True:
  try:
    l.remove("")
  except ValueError:
    break

这的优势不是创建一个新的列表,但缺点的每次搜索从一开始,尽管不像使用while '' in l正如上面提出的,它只需要搜索一次每发生''(当然是有办法保持最好的两种方法,但它是更复杂)。


使用filter:

1
newlist=filter(lambda x: len(x)>0, oldlist)

正如所指出的,使用filter的缺点是它比其他方法慢;此外,lambda通常是昂贵的。

或者你也可以选择最简单最迭代的:

1
2
3
4
5
# I am assuming listtext is the original list containing (possibly) empty items
for item in listtext:
    if item:
        newlist.append(str(item))
# You can remove str() based on the content of your original list

这是最直观的方法,而且是在合适的时间完成的。


请记住,如果希望将空白保留在字符串中,可以使用一些方法无意中删除它们。如果你有这个列表

['hello world', ', ', ', 'hello']你想要什么['hello world','hello']

首先修剪列表,将任何类型的空白转换为空字符串:

1
space_to_empty = [x.strip() for x in _text_list]

然后从它们的列表中删除空字符串

1
space_clean_list = [x for x in space_to_empty if x]

正如Aziz Alto filter(None, lstr)所报告的,不使用空格' '删除空字符串,但是如果您确定lstr只包含字符串,则可以使用filter(str.strip, lstr)

1
2
3
4
5
6
7
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(str.strip, lstr)
['hello', 'world']

比较一下我电脑上的时间

1
2
3
4
5
>>> from timeit import timeit
>>> timeit('"".join(lstr).split()',"lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.356455087661743
>>> timeit('filter(str.strip, lstr)',"lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
5.276503801345825

使用空格' '删除''和空字符串的最快解决方案仍然是' '.join(lstr).split()

如注释中所述,如果字符串包含空格,情况就不同了。

1
2
3
4
5
6
7
>>> lstr = ['hello', '', ' ', 'world', '    ', 'see you']
>>> lstr
['hello', '', ' ', 'world', '    ', 'see you']
>>> ' '.join(lstr).split()
['hello', 'world', 'see', 'you']
>>> filter(str.strip, lstr)
['hello', 'world', 'see you']

您可以看到filter(str.strip, lstr)保留带空格的字符串,但是' '.join(lstr).split()将分割这个字符串。


为了消除剥离后的空洞:

1
2
slist = map(lambda s: s and s.strip(), slist)
slist = filter(None, slist)

一些优点:

懒惰,基于生成器,节省内存;代码的可理解性;

快速、有选择地使用内建和理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def f1(slist):
    slist = [s and s.strip() for s in slist]
    return list(filter(None, slist))

def f2(slist):
    slist = [s and s.strip() for s in slist]
    return [s for s in slist if s]


def f3(slist):
    slist = map(lambda s: s and s.strip(), slist)
    return list(filter(None, slist))

def f4(slist):
    slist = map(lambda s: s and s.strip(), slist)
    return [s for s in slist if s]

%timeit f1(words)
10000 loops, best of 3: 106 μs per loop

%timeit f2(words)
10000 loops, best of 3: 126 μs per loop

%timeit f3(words)
10000 loops, best of 3: 165 μs per loop

%timeit f4(words)
10000 loops, best of 3: 169 μs per loop


1
2
3
4
5
str_list = ['2', '', '2', '', '2', '', '2', '', '2', '']

for item in str_list:
    if len(item) < 1:  
        str_list.remove(item)

短暂而甜蜜的。


filter(None, str)不删除带有空格''的空字符串,它只删除''和''。

join(str).split()删除。但是如果你的列表元素有空间它会改变你的列表元素因为它首先加入了你所有的列表元素然后按空间来添加所以你应该使用:-

1
2
str = ['hello', '', ' ', 'world', ' ']
print filter(lambda x:x != '', filter(lambda x:x != ' ', str))

它将删除这两个元素,并且不会影响您的元素如:-

1
2
3
str = ['hello', '', ' ', 'world ram', ' ']
print  ' '.join(lstr).split()
print filter(lambda x:x != '', filter(lambda x:x != ' ', lstr))

输出:

['你好','世界',' ram '] < - - - - - - - - - - - - - - - - ' '.join(lstr).split()的输出("你好","世界ram")


循环遍历现有字符串列表,然后检查是否为空字符串,如果不是空字符串,则用非空值填充新字符串列表,然后用新字符串列表替换旧字符串列表