去除字符串末尾空格的 Pythonic 方法是什么?
这个函数的参数需要满足以下规则:
- 开头不能有空格
- 结尾可以有空格
- 字符串中可能会有夹杂的空格。
目标:去掉夹杂的重复空格,并去掉结尾的空格。
这是我现在的做法:
# toks - a priori no leading space
def squeeze(toks):
import re
p = re.compile(r'\W+')
a = p.split( toks )
for i in range(0, len(a)):
if len(a[i]) == 0:
del a[i]
return ' '.join(a)
>>> toks( ' Mary Decker is hot ' )
Mary Decker is hot
这样做可以改进吗?够Python风格吗?
6 个回答
2
来直接回答你的问题:
是的,这个代码可以改进。第一个改进就是让它能正常工作。
>>> squeeze('x ! y')
'x y' # oops
问题1:你用的是 \W+(非单词字符),其实应该用 \s+(空白字符)
>>> toks = 'x ! y z '
>>> re.split('\W+', toks)
['x', 'y', 'z', '']
>>> re.split('\s+', toks)
['x', '!', 'y', 'z', '']
问题2:你用来删除空字符串的循环是有效的,但这只是偶然的结果。 如果你想要一个通用的循环来删除空字符串,你应该从后往前处理,不然你的索引 i 会和剩下的元素数量不匹配。这里之所以能工作,是因为 re.split() 在没有捕获组的情况下,只会在开头和结尾产生空元素。你已经解决了开头的问题,而结尾的情况也没问题,因为之前没有删除过元素。所以你现在的循环很复杂,其实可以用两行代码来替代:
if a and not a[-1]: # guard against empty list
del a[-1]
不过,除非你的字符串非常长,而且你担心速度(在这种情况下你可能不应该使用 re),否则你可能想考虑前面的空白(通常大家都默认“我的数据没有前导空白”这种说法是无效的),可以直接在循环中处理:
a = [x for x in p.split(toks) if x]
接下来的步骤是避免构建列表 a
:
return ' '.join(x for x in p.split(toks) if x)
你提到“Pythonic”... 所以我们可以把所有的 re 导入和编译的复杂操作都扔掉,直接这样做:
return ' '.join(toks.split())
4
你不能用 rstrip() 吗?
some_string.rstrip()
或者用 strip() 来去掉字符串两边的空白呢?
另外:strip() 方法还支持传入你想去掉的特定字符:
string.strip = strip(s, chars=None)
strip(s [,chars]) -> string
相关内容:如果你需要去掉中间的空白,可以把字符串分开,去掉每个部分的空白,然后再把它们合并起来。
阅读 API 文档会有帮助哦!
9
我会这样做:
" ".join(toks.split())
顺便问一下,这个问题里有没有潜在的信息呢?;-)