我想从python中的字符串列表中删除所有空字符串。
我的想法如下:
while '' in str_list:
str_list.remove('')
还有其他pythonic方式可以做到这一点吗?
for var in list:
,但是在这里,他已经写了while const in list:
。这并没有遍历任何东西。它只是重复相同的代码,直到条件为假。
我想从python中的字符串列表中删除所有空字符串。
我的想法如下:
while '' in str_list:
str_list.remove('')
还有其他pythonic方式可以做到这一点吗?
for var in list:
,但是在这里,他已经写了while const in list:
。这并没有遍历任何东西。它只是重复相同的代码,直到条件为假。
Answers:
我会使用filter
:
str_list = filter(None, str_list)
str_list = filter(bool, str_list)
str_list = filter(len, str_list)
str_list = filter(lambda item: item, str_list)
Python 3从返回一个迭代器filter
,因此应包装在对的调用中list()
str_list = list(filter(None, str_list))
itertool
的ifilter
甚至faster- >>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.3468542098999023
; >>> timeit('itertools.ifilter(None, str_list)', 'str_list=["a"]*1000', number=100000)
0.04442191123962402
。
ifilter
结果的评估是懒惰的,而不是一go而就的-我认为在大多数情况下ifilter
是更好的选择。有趣的是,使用filter
它仍然比包装ifilter
in 更快list
。
>>> 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)
它不会删除带有空格的空字符串' '
,只会修剪掉''
而同时' '.join(lstr).split()
删除它们。
要使用filter()
删除的空格字符串,需要花费更多时间:
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
filter(None, lstr)
不会删除带有空格的空字符串,' '
是的,因为那不是空字符串。
代替if x,我将使用if X!=”来消除空字符串。像这样:
str_list = [x for x in str_list if x != '']
这将在列表中保留“无”数据类型。此外,如果您的列表中有整数,并且0是其中的一个,它也将被保留。
例如,
str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
str_list = [None, '', 0, "Hi", '', "Hello"]
,则表明应用程序设计不佳。在同一列表中,您不应有多个接口(类型)和“无”。
根据列表的大小,如果您使用list.remove()而不是创建新列表,则可能是最有效的:
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
这具有不创建新列表的优点,但是具有每次都必须从头开始搜索的缺点,尽管与while '' in l
上面建议的用法不同,它每次出现时仅需要搜索一次''
(当然,有一种方法可以保持最佳状态)两种方法,但更为复杂)。
ary[:] = [e for e in ary if e]
。更干净,不使用异常进行控制。
请记住,如果要将空格保留在字符串中,则可以使用某些方法无意中将其删除。如果你有这个清单
['hello world','',','hello']您可能想要的内容['hello world','hello']
首先修剪列表以将任何类型的空格转换为空字符串:
space_to_empty = [x.strip() for x in _text_list]
然后从列表中删除空字符串
space_clean_list = [x for x in space_to_empty if x]
space_clean_list = [x.strip() for x in y if x.strip()]
用途filter
:
newlist=filter(lambda x: len(x)>0, oldlist)
如所指出的,使用过滤器的缺点是它比替代方法慢。而且,lambda
通常很昂贵。
或者,您可以选择最简单,最迭代的方法:
# 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
这是最直观的方法,并且可以在适当的时间内完成。
lambda x: len(x)
是不如lambda x : x
这是最坏的选择答案的4个解决方案。正确的功能是首选,但还不够。将光标悬停在向下投票按钮上:提示“此答案无用”。
正如Aziz Alto 所报告的filter(None, lstr)
那样,不会删除带有空格的空字符串,' '
但是如果您确定lstr仅包含字符串,则可以使用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
删除''
和清空带有空格的字符串的最快解决方案' '
仍然是' '.join(lstr).split()
。
如评论中所述,如果您的字符串包含空格,则情况会有所不同。
>>> 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()
会拆分这些字符串。
join
解决方案时,@ BenPolinsky 将使用空格分割字符串,但过滤器不会。谢谢您的评论,我的回答有所改善。
也就是说,保留所有空格字符串:
slist = list(filter(None, slist))
优点:
slist = ' '.join(slist).split()
优点:
slist = list(filter(str.strip, slist))
优点:
## Build test-data
#
import random, string
nwords = 10000
maxlen = 30
null_ratio = 0.1
rnd = random.Random(0) # deterministic results
words = [' ' * rnd.randint(0, maxlen)
if rnd.random() > (1 - null_ratio)
else
''.join(random.choices(string.ascii_letters, k=rnd.randint(0, maxlen)))
for _i in range(nwords)
]
## Test functions
#
def nostrip_filter(slist):
return list(filter(None, slist))
def nostrip_comprehension(slist):
return [s for s in slist if s]
def strip_filter(slist):
return list(filter(str.strip, slist))
def strip_filter_map(slist):
return list(filter(None, map(str.strip, slist)))
def strip_filter_comprehension(slist): # waste memory
return list(filter(None, [s.strip() for s in slist]))
def strip_filter_generator(slist):
return list(filter(None, (s.strip() for s in slist)))
def strip_join_split(slist): # words without(!) spaces
return ' '.join(slist).split()
## Benchmarks
#
%timeit nostrip_filter(words)
142 µs ± 16.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit nostrip_comprehension(words)
263 µs ± 19.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter(words)
653 µs ± 37.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_map(words)
642 µs ± 36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_comprehension(words)
693 µs ± 42.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_filter_generator(words)
750 µs ± 28.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit strip_join_split(words)
796 µs ± 103 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
s and s.strip()
可以简化为s.strip()
。
s and s.strip()
如果我们要完全复制filter(None, words)
已接受的答案,则需要此选项。我更正了上面的x2示例函数,并删除了x2错误的函数。
对于包含空格和空值的列表,请使用简单的列表理解-
>>> s = ['I', 'am', 'a', '', 'great', ' ', '', ' ', 'person', '!!', 'Do', 'you', 'think', 'its', 'a', '', 'a', '', 'joke', '', ' ', '', '?', '', '', '', '?']
因此,您可以看到,此列表包含空格和null元素的组合。使用摘要-
>>> d = [x for x in s if x.strip()]
>>> d
>>> d = ['I', 'am', 'a', 'great', 'person', '!!', 'Do', 'you', 'think', 'its', 'a', 'a', 'joke', '?', '?']
for x in list
要使用的迭代列表。如果您使用,while loop
那么就可以了。演示的循环将删除空字符串,直到不再有空字符串,然后停止。实际上,我什至没有看过这个问题(只是标题),但是我回答的可能性完全相同!如果您不想为了存储而使用解析或过滤器,那是一个非常Python的解决方案。