用逗号分割并在Python中去除空格


346

我有一些在逗号处分割的python代码,但没有去除空格:

>>> string = "blah, lots  ,  of ,  spaces, here "
>>> mylist = string.split(',')
>>> print mylist
['blah', ' lots  ', '  of ', '  spaces', ' here ']

我宁愿这样删除空格:

['blah', 'lots', 'of', 'spaces', 'here']

我知道我可以遍历list和strip()每个项目,但是,因为这是Python,所以我猜有一种更快,更轻松和更优雅的方法。

Answers:


593

使用列表理解-更简单,就像for循环一样容易阅读。

my_string = "blah, lots  ,  of ,  spaces, here "
result = [x.strip() for x in my_string.split(',')]
# result is ["blah", "lots", "of", "spaces", "here"]

请参阅: 有关列表理解的Python文档
很好的2秒钟的列表理解说明。


1
非常好!我添加了以下一项,以摆脱空白列表条目。>文本= [如果x!='',则text.split('。')中的x为x.strip()
RandallShanePhD

@Sean:无效/不完整的python代码是您的“帖子原始意图”吗?根据评论的要求,它是:stackoverflow.com/review/suggested-edits/21504253。如果错误(再次),您可以通过更正来告诉他们吗?
牧草

原始文件是从R​​EPL复制粘贴的(如果我没记错的话),目标是理解基本概念(使用列表理解来执行操作),但是您是对的,如果看到列表理解就更有意义了。产生一个新列表。
肖恩·维埃拉

24

使用正则表达式拆分。注意我用前导空格使情况更一般。列表理解是删除前面和后面的空字符串。

>>> import re
>>> string = "  blah, lots  ,  of ,  spaces, here "
>>> pattern = re.compile("^\s+|\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['blah', 'lots', 'of', 'spaces', 'here']

即使^\s+不匹配也可以:

>>> string = "foo,   bar  "
>>> print([x for x in pattern.split(string) if x])
['foo', 'bar']
>>>

这就是您需要^ \ s +的原因:

>>> pattern = re.compile("\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['  blah', 'lots', 'of', 'spaces', 'here']

看到等等的主要空间吗?

说明:上面使用的是Python 3解释器,但结果与Python 2相同。


8
我相信[x.strip() for x in my_string.split(',')]对于提出的问题来说,它更具Python性。也许在某些情况下我的解决方案是必要的。如果碰到一个内容,我将对其进行更新。
tbc0

为什么有^\s+必要?我已经在没有它的情况下测试了您的代码,但它不起作用,但是我不知道为什么。
laike9m

如果我使用re.compile("^\s*,\s*$"),结果是[' blah, lots , of , spaces, here ']
laike9m

@ laike9m,我更新了我的答案以向您显示差异。^\s+制造。如您所见,^\s*,\s*$也不会返回期望的结果。因此,如果您想使用正则表达式进行拆分,请使用^\s+|\s*,\s*|\s+$
tbc0

如果前导模式(^ \ s +)不匹配,则第一个匹配为空,因此对于字符串“ foo,bar”,您会得到类似[”,“ foo”,“ bar”]的信息。
Steeve McCauley

21

我来补充:

map(str.strip, string.split(','))

但是看到Jason Orendorff在评论中已经提到了它。

在同一个答案中读到格伦·梅纳德(Glenn Maynard)的评论,这暗示着人们对地图的理解,我开始怀疑为什么。我以为他是出于性能方面的考虑,但是当然他可能是出于风格方面的原因,或者其他原因(Glenn?)。

因此,在我的盒子上快速地(可能有缺陷?)应用了以下三种方法的测试:

[word.strip() for word in string.split(',')]
$ time ./list_comprehension.py 
real    0m22.876s

map(lambda s: s.strip(), string.split(','))
$ time ./map_with_lambda.py 
real    0m25.736s

map(str.strip, string.split(','))
$ time ./map_with_str.strip.py 
real    0m19.428s

map(str.strip, string.split(','))赢家,但它似乎他们都在同一个球场。

当然,出于性能原因,不一定要排除map(有或没有lambda),对我而言,它至少与列表理解一样清晰。

编辑:

Ubuntu 10.04上的Python 2.6.5


15

分割字符串之前,只需从字符串中删除空格。

mylist = my_string.replace(' ','').split(',')

10
如果用逗号分隔的项目包含嵌入式空格(例如),则是一种问题"you just, broke this"
罗伯特·罗斯尼

1
吉兹,为此-1。你们很难。它解决了他的问题,条件是他的样本数据仅是一个单词,而没有说明该数据将是短语。但是,w / e,我想这就是你们在这里转来转去的方式。
user489041 '11

好的,谢谢用户。公平地说,尽管我专门要求split,然后strip()和strip删除前导和尾随空格,并且在两者之间没有任何接触。稍作更改,您的答案就可以完美地工作:mylist = mystring.strip()。split(','),尽管我不知道这样做是否特别有效。
Mr_Chimp

12

我知道已经回答了这个问题,但是如果您结束很多工作,则使用正则表达式可能是更好的选择:

>>> import re
>>> re.sub(r'\s', '', string).split(',')
['blah', 'lots', 'of', 'spaces', 'here']

\s匹配任何空白字符,我们只是用一个空字符串替换它''。您可以在此处找到更多信息:http : //docs.python.org/library/re.html#re.sub


3
您的示例不适用于包含空格的字符串。“例如,这个,一个”将变为“例如,”,“这个,一个”。并不是说这是一个BAD解决方案(在我的示例中效果很好),它仅取决于手头的任务!
Mr_Chimp

是的,这是非常正确的!您可能可以调整正则表达式,使其可以处理带空格的字符串,但是如果列表理解有效,我会说坚持下去;)
Brad Montgomery 2012年

2
import re
result=[x for x in re.split(',| ',your_string) if x!='']

这对我来说很好。


2

re (如正则表达式中一样)允许一次分割多个字符:

$ string = "blah, lots  ,  of ,  spaces, here "
$ re.split(', ',string)
['blah', 'lots  ', ' of ', ' spaces', 'here ']

这对于您的示例字符串而言效果不佳,但对于逗号分隔的列表则效果很好。对于您的示例字符串,您可以结合使用re.split功能来分割正则表达式模式,从而获得“按此分割”效果。

$ re.split('[, ]',string)
['blah',
 '',
 'lots',
 '',
 '',
 '',
 '',
 'of',
 '',
 '',
 '',
 'spaces',
 '',
 'here',
 '']

不幸的是,这很丑陋,但是a filter会成功的:

$ filter(None, re.split('[, ]',string))
['blah', 'lots', 'of', 'spaces', 'here']

瞧!


2
为什么不只是re.split(' *, *', string)呢?
Paul Tomblin

4
@PaulTomblin好主意。一个人也可以这样做:re.split('[, ]*',string)达到相同的效果。
丹妮德2015年

Dannid在写完之后意识到,它并没有像@ tbc0的答案那样在开头和结尾去除空格。
Paul Tomblin 2015年

@PaulTomblinheh,我的反对[, ]*在列表末尾留下了一个空字符串。我认为过滤器仍然是不错的选择,或者像顶级答案一样坚持列表理解。
丹妮德

1

map(lambda s: s.strip(), mylist)比显式循环要好一点。或一次全部:map(lambda s:s.strip(), string.split(','))


10
提示:每当您发现自己正在使用时map,尤其是如果您正在使用lambda它,请仔细检查以查看是否应该使用列表推导。
Glenn Maynard

11
您可以使用避免使用lambda map(str.strip, s.split(','))
杰森·奥伦多夫


1
import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)]

简单地说,用逗号或至少一个空白空格,带有/没有在前/在后的空格。

请试试!


0

map(lambda s: s.strip(), mylist)比显式循环要好一点。
或一次全部:

map(lambda s:s.strip(), string.split(','))

这基本上就是您需要的一切。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.