我的想法如下:
while '' in str_list:
str_list.remove('')
是否还有更多pythonic的方法来做到这一点?
#1 楼
我将使用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甚至会更快— >>> 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。
–汉弗莱·鲍嘉(Humphrey Bogart)
2011年7月21日在11:02
@cpburnz非常正确。但是,使用ifilter时,结果会被懒惰地评估,而不是一in而就-我认为在大多数情况下,ifilter更好。有趣的是,使用filter仍然比将ifilter包裹在列表中更快。
–汉弗莱·鲍嘉(Humphrey Bogart)
2012-09-14 11:03
如果对一个数字列表执行此操作,请注意,零也将被删除(注意:我仅使用前三种方法),因此您将需要一个替代方法。
–SnoringFrog
2014年4月22日在6:29
这仅关注速度,而不关注解决方案的pythonic(提出的问题)。 List Comprehensions是pythonic解决方案,仅当分析证明listcomp是瓶颈时才应使用filter。
– Tritium21
2015年2月21日在18:18
@ whoever-mentions-about-or-imply-Python-3,请仅编辑和更新答案。当问到这个问题时,我们只是在讨论Python 2,甚至Python 3发行了将近两年。但是请同时更新Python 2和3的结果。
–活力十足
16-3-29在22:22
#2 楼
使用列表理解是最Python化的方法:使用切片分配:>>> strings = ["first", "", "second"]
>>> [x for x in strings if x]
['first', 'second']
评论
我喜欢这个解决方案,因为它很容易适应。如果我不仅需要删除空字符串,还需要删除仅是空格的字符串,例如:[如果x.strip(),则为字符串中的x。
–债券
15年12月29日在16:28
#3 楼
filter实际上对此有一个特殊的选择:filter(None, sequence)
或python 3:
list(filter(None, sequence))
它将过滤出所有评估为False的元素。这里不需要使用实际的可调用对象,例如bool,len等。
与map(bool,...)
一样快
评论
实际上,这是一个python习语。这也是我唯一一次仍然使用filter(),列表推导已经接管了其他所有地方。
–加莱辛
14年2月18日在8:24
与list comp相比,我发现这更容易理解代码的意图
–马丁CR
12月17日13:10
#4 楼
>>> 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
评论
如果单词的字符串之间有空格,它将无法正常工作。例如:['hello world','','hello','']。 >> ['helloworld','','hello','']您是否还有其他解决方案,可以在列表中的项目中保留空格,但删除其他项目?
– Reihan_amn
18年2月6日在19:06
请注意filter(None,lstr)不会删除带有空格''的空字符串,因为那不是空字符串。
– AMC
1月9日20:41
#5 楼
@ Ib33X的回复很棒。如果要删除每个空字符串,请剥离后。您也需要使用strip方法。否则,如果有空格,它将也返回空字符串。例如,“”对于该答案也将有效。因此,可以通过以下方法实现。strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
答案将是
["first", "second"]
。如果要使用
filter
方法,则可以可以像list(filter(lambda item: item.strip(), strings))
这样。这给出了相同的结果。#6 楼
代替if x,我将使用if X!=”来消除空字符串。像这样:str_list = [x for x in str_list if x != '']
这将在列表中保留无数据类型。另外,如果您的列表包含整数并且0是其中的一个,它也将被保留。
例如
评论
如果您的列表具有不同的类型(“无”除外),则可能会有更大的问题。
– Tritium21
2015年2月21日在18:14
什么类型的我尝试了int和其他数字类型,字符串,列表,元组,集合和None,并且在那里没有问题。我可以看到,如果有任何不支持str方法的用户定义类型可能会出现问题。我应该担心其他吗?
– thiruvenkadam
2015年2月23日下午6:53
如果您的str_list = [None,'',0,“ Hi”,'',“ Hello”],则表明该应用程序设计不良。在同一列表中,您不应有多个接口(类型)和“无”。
– Tritium21
2015年2月23日下午16:21
从数据库检索数据?自动测试时函数的参数列表?
– thiruvenkadam
15年2月24日在5:22
这些通常是元组。
– Tritium21
15年2月24日在10:47
#7 楼
根据列表的大小,如果您使用list.remove()而不是创建新列表,则可能是最高效的:l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
并非创建新列表,而是每次都必须从头开始搜索的缺点,尽管与上述建议使用
while '' in l
不同,它每次出现''
时仅需要搜索一次(当然,有一种方法可以使两种方法保持最佳状态,但是比较复杂)。评论
您可以通过执行ary [:] = [e中的e代表ary,如果e]来就地编辑列表。更干净,不使用异常的控制流。
– Krzysztof Karski
17年6月28日在12:01
好吧,这并不是真正的“到位”-我很确定这会创建一个新列表并将其分配给旧名称。
–安德鲁·贾菲(Andrew Jaffe)
18年8月13日在9:22
由于每次删除时数据的尾部都会在内存中随机移动,因此执行效果非常差。最好一次性删除所有内容。
– Wim
1月9日22:27
#8 楼
请记住,如果要将空格保留在字符串中,可以使用某些方法无意中将其删除。如果有此列表
['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]
评论
如果要将空格保留在字符串中,则可以使用某些方法无意中将其删除。像这样的方法呢?
– AMC
1月9日20:49
感谢dude,它为我做了一点改动。即space_clean_list = [如果x.strip()为y中的x,则为x.strip()]
–穆罕默德·迈赫兰·汗·阿塔里(Muhammad Mehran Khan Attari)
1月26日8:56
#9 楼
使用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
方法并在适当的时间完成。
评论
欢迎来到SO。您没有被忽略。您尚未受到任何不赞成投票的人的攻击。您已收到反馈。放大:您建议的第一个arg过滤器比lambda x:len(x)差,而lambda x:len(x)差于lambda x:x,后者是所选答案中4个解中最差的。正确的功能是首选,但还不够。将光标悬停在向下投票按钮上:提示“此答案无用”。
–约翰·马钦(John Machin)
2012年1月11日在11:23
#10 楼
正如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']
删除
''
和带有空格' '
的空字符串的最快解决方案仍然是' '.join(lstr).split()
。如果您的字符串中包含空格。评论
仅当您的字符串不包含空格时,此方法才有效。否则,您也将拆分这些字符串。
– phillyslick
17年7月25日在13:32
您报告的联接解决方案@BenPolinsky将使用空格分割字符串,但过滤器不会。谢谢您的评论,我的回答有所改善。
–保罗·梅尔基奥尔(Paolo Melchiorre)
17年8月31日在8:07
#11 楼
总结最佳答案:1。消除空号而无需剥离:
,即保留所有空格字符串:
最简单;
最快(请参见下面的基准)。
2。要在剥离后消除空值...
2.a ...当字符串在单词之间不包含空格时:
小代码
快速
(但是由于内存的原因,大数据集的速度不是最快,与@ paolo-melchiorre结果相反) > 2.b ...当字符串在单词之间包含空格时?
slist = list(filter(None, slist))
代码的可理解性。
2018年计算机上的基准:
slist = ' '.join(slist).split()
评论
s和s.strip()可以简化为s.strip()。
– AMC
1月9日20:53
如果我们要完全复制已接受的答案filter(无,单词),则需要s和s.strip()。我更正了上面的x2示例函数,并删除了x2错误的函数。
– ankostis
1月10日10:46
#12 楼
对于包含空格和空值的组合的列表,请使用简单的列表理解->>> 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', '?', '?']
评论
@Ivo,这些陈述都不正确。您永远不要修改列表中用于x的迭代列表。如果您使用while循环,那就没问题了。演示的循环将删除空字符串,直到不再有空字符串,然后停止。实际上,我什至没有看过这个问题(只是标题),但是我回答的可能性完全一样!如果您不想为了存储而使用解析或过滤器,那是一个非常Python化的解决方案。永远不要更改您要遍历的列表仍然是非常有效的一点:)
@EduardLuca如果要遍历列表是要更改它,那么这与您应该做的相反。您只需要小心,就可以知道自己不会引起意外的行为。
@ EduardLuca,@ JFA:重点是他没有遍历任何列表。如果他以var in list:的形式写过东西,他会的,但是在这里,他在const in list:中写了。这并没有遍历任何东西。只是重复相同的代码,直到条件为假。
您可以使用过滤器删除空字符串。代码应如下所示:data = list(filter(None,str_list))