去除字符串末尾空格的 Pythonic 方法是什么?

3 投票
6 回答
5340 浏览
提问于 2025-04-16 16:57

这个函数的参数需要满足以下规则:

  1. 开头不能有空格
  2. 结尾可以有空格
  3. 字符串中可能会有夹杂的空格。

目标:去掉夹杂的重复空格,并去掉结尾的空格。

这是我现在的做法:

# 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())

顺便问一下,这个问题里有没有潜在的信息呢?;-)

撰写回答