从string列表中删除空string

我想从Python中的string列表中删除所有空string。

我的想法是这样的:

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

有没有更pythonic的方式来做到这一点?

我会使用filter

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

Python 3从filter返回一个迭代filter ,所以应该包装在一个调用list()

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

testing:

 >>> 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 

列表parsing

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

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

编辑:缩短build议

filter实际上有一个特殊的select:

 filter(None, sequence) 

它会过滤出所有评估为False的元素。 不需要在这里使用实际的可调用函数,比如bool,len等。

它和map(bool,…)一样快

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

比较时间

 >>> 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)不会删除带空格' '空stringfilter(None, lstr)删除''' '.join(lstr).split()删除这两个' '.join(lstr).split()

要使用filter()删除空白string,它需要更多的时间:

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

而不是如果x,我会使用如果X!=''为了消除空string。 喜欢这个:

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

这将在您的列表中保留无数据types。 而且,如果你的列表有整数,0是其中的一个,它也将被保留。

例如,

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

@ Ib33X的回复非常棒。 如果你想删除每个空string,剥离后。 你也需要使用strip方法。 否则,如果它有空格,它也会返回空string。 就像这个答案,“”也是有效的。 所以,可以通过。

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

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

使用filter

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

指出使用filter的缺点是它比替代方法慢; 而且, lambda通常是昂贵的。

或者你可以select最简单也是最重复的:

 # 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 

这是最直观的方法,并在体面的时间。

根据列表的大小,如果使用list.remove()而不是创build一个新列表,这可能是最有效的:

 l = ["1", "", "3", ""] while True: try: l.remove("") except ValueError: break 

这样做的优点是不会创build一个新的列表,但是每次从头开始search的缺点,虽然不像上面提出的那样使用while '' in l ,但是每次发生只需要search一次(当然一种保持两种方法最好的方法,但它更复杂)。

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

 >>> lstr = ['hello', '', ' ', 'world', ' '] >>> lstr ['hello', '', ' ', 'world', ' '] >>> ' '.join(lstr).split() ['hello', 'world'] >>> filter(str.strip, lstr) ['hello', 'world'] 

比较我的电脑上的时间

 >>> 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 

用空格删除''和空string''的最快解决scheme仍然是' '.join(lstr).split()

正如在评论中所报道的,如果你的string包含空格,情况就不一样

 >>> 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)保留了带有空格的string,但' '.join(lstr).split()将分割这些string。

为了消除剥离后的空白:

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

一些PROs:

  • 懒惰,基于生成器,以节省内存;
  • 代码体面的可理解性;
  • 快速,有select地使用内置和理解。

     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 
 str_list = ['2', '', '2', '', '2', '', '2', '', '2', ''] for item in str_list: if len(item) < 1: str_list.remove(item) 

简短而甜蜜。

循环现有的string列表,然后检查一个空string,如果它不是空的,用非空值填充一个新的string列表,然后用新的string列表replace旧的string列表

filter(None, str)不会删除带有空格的空string,它只会删除“'和”'。

join(str).split()删除两者。 但是如果你的列表中的元素有空间,那么它将改变你的列表元素,因为它首先join列表中的所有元素,然后通过空间来分配它们,所以你应该使用:

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

它会删除两个,并不会影响你的元素也像:

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

输出: –

['hello','world','ram'] <————– ' '.join(lstr).split()输出' '.join(lstr).split()
['你好','世界公羊']