我想从python中的字符串列表中删除所有空字符串。

我的想法如下:

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


是否还有更多pythonic的方法来做到这一点?

评论

@Ivo,这些陈述都不正确。您永远不要修改列表中用于x的迭代列表。如果您使用while循环,那就没问题了。演示的循环将删除空字符串,直到不再有空字符串,然后停止。实际上,我什至没有看过这个问题(只是标题),但是我回答的可能性完全一样!如果您不想为了存储而使用解析或过滤器,那是一个非常Python化的解决方案。

永远不要更改您要遍历的列表仍然是非常有效的一点:)

@EduardLuca如果要遍历列表是要更改它,那么这与您应该做的相反。您只需要小心,就可以知道自己不会引起意外的行为。

@ EduardLuca,@ JFA:重点是他没有遍历任何列表。如果他以var in list:的形式写过东西,他会的,但是在这里,他在const in list:中写了。这并没有遍历任何东西。只是重复相同的代码,直到条件为假。

您可以使用过滤器删除空字符串。代码应如下所示:data = list(filter(None,str_list))

#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', '?', '?']