从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()
['你好','世界公羊']