zer*_*odx 632 python arrays string list
我想从python中的字符串列表中删除所有空字符串.
我的想法是这样的:
while '' in str_list:
str_list.remove('')
Run Code Online (Sandbox Code Playgroud)
有没有更多的pythonic方式来做到这一点?
liv*_*ter 1066
我会用filter
:
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
Run Code Online (Sandbox Code Playgroud)
Python 3从中返回一个迭代器filter
,因此应该包含在调用中list()
str_list = list(filter(None, str_list)) # fastest
Run Code Online (Sandbox Code Playgroud)
(等)
测试:
>>> 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
Run Code Online (Sandbox Code Playgroud)
Ib3*_*33X 210
strings = ["first", "", "second"]
[x for x in strings if x]
Run Code Online (Sandbox Code Playgroud)
输出: ['first', 'second']
编辑:按建议缩短
Ivo*_*ijk 63
filter实际上有一个特殊的选项:
filter(None, sequence)
Run Code Online (Sandbox Code Playgroud)
它将过滤掉所有评估为False的元素.这里不需要使用实际的可调用语句,如bool,len等.
它和地图一样快(bool,......)
Azi*_*lto 22
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(None, lstr)
['hello', ' ', 'world', ' ']
Run Code Online (Sandbox Code Playgroud)
比较时间
>>> 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
Run Code Online (Sandbox Code Playgroud)
请注意,filter(None, lstr)
不会删除带有空格的空字符串' '
,只会''
在' '.join(lstr).split()
删除两者时将其删除.
要filter()
删除空白字符串,需要花费更多时间:
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
Run Code Online (Sandbox Code Playgroud)
Adi*_*tya 15
你可以使用这样的东西
test_list = [i for i in test_list if i]
Run Code Online (Sandbox Code Playgroud)
其中 test_list 是要从中删除空元素的列表。
ssi*_*nik 12
来自@ Ib33X的回复太棒了.如果要在剥离后删除每个空字符串.你也需要使用strip方法.否则,如果它有空格,它也将返回空字符串.就像,""对于那个答案也是有效的.所以,可以通过实现.
strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
Run Code Online (Sandbox Code Playgroud)
答案就是这样["first", "second"]
.
如果你想使用filter
方法,你可以这样做
list(filter(lambda item: item.strip(), strings))
.这给出了相同的结果.
thi*_*dam 11
而不是if,我会使用X!=''来消除空字符串.像这样:
str_list = [x for x in str_list if x != '']
Run Code Online (Sandbox Code Playgroud)
这将在列表中保留None数据类型.此外,如果您的列表有整数,0是其中之一,它也将被保留.
例如,
str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
Run Code Online (Sandbox Code Playgroud)
根据列表的大小,如果使用list.remove()而不是创建新列表,则效率最高:
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
Run Code Online (Sandbox Code Playgroud)
这样做的好处是不会创建新的列表,但每次都必须从头开始搜索,但不像while '' in l
上面提到的那样,它只需要每次搜索一次''
(有一种方法可以保持最佳状态)两种方法,但它更复杂).
小智 7
用途filter
:
newlist=filter(lambda x: len(x)>0, oldlist)
Run Code Online (Sandbox Code Playgroud)
指出使用过滤器的缺点是它比替代品慢; 此外,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
Run Code Online (Sandbox Code Playgroud)
这是最直观的方法,并且在适当的时间内完成.
也就是说,保留所有空格的字符串:
slist = list(filter(None, slist))
Run Code Online (Sandbox Code Playgroud)
优点:
slist = ' '.join(slist).split()
Run Code Online (Sandbox Code Playgroud)
优点:
slist = list(filter(str.strip, slist))
Run Code Online (Sandbox Code Playgroud)
优点:
## 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)
Run Code Online (Sandbox Code Playgroud)
请记住,如果要将白色空格保留在字符串中,可以使用某些方法无意中删除它们.如果你有这个清单
['你好世界','','','你好']你可能想要什么['你好世界','你好']
首先修剪列表以将任何类型的空格转换为空字符串:
space_to_empty = [x.strip() for x in _text_list]
Run Code Online (Sandbox Code Playgroud)
然后从列表中删除空字符串
space_clean_list = [x for x in space_to_empty if x]
Run Code Online (Sandbox Code Playgroud)
据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']
Run Code Online (Sandbox Code Playgroud)
比较我的电脑上的时间
>>> 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
Run Code Online (Sandbox Code Playgroud)
删除''
和清空带有空格的字符串的最快解决方案' '
仍然存在' '.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']
Run Code Online (Sandbox Code Playgroud)
您可以看到filter(str.strip, lstr)
保留带有空格的字符串,但' '.join(lstr).split()
会拆分此字符串.