计算字符串中前导空格的Python方法是什么?

计算字符串中前导空格的Python方法是什么?,python,Python,我知道我可以用以下方法计算字符串中的前导空格: >>> a = " foo bar baz qua \n" >>> print "Leading spaces", len(a) - len(a.lstrip()) Leading spaces 3 >>> 但是有没有更像蟒蛇的方式呢?看起来。。。太好了。通常我会用一些函数魔法来回答“X Pythonic吗?”的问题,但我觉得这种方法不适合字符串操作 如果有一个只返回前导空格的内置函数

我知道我可以用以下方法计算字符串中的前导空格:

>>> a = "   foo bar baz qua   \n"
>>> print "Leading spaces", len(a) - len(a.lstrip())
Leading spaces 3
>>>

但是有没有更像蟒蛇的方式呢?

看起来。。。太好了。通常我会用一些函数魔法来回答“X Pythonic吗?”的问题,但我觉得这种方法不适合字符串操作


如果有一个只返回前导空格的内置函数,并且使用了
len()
,我会说,去吧-但很快就没有了,而且
re
和其他解决方案绝对是多余的。

你可以使用
itertools.takewhile

sum( 1 for _ in itertools.takewhile(str.isspace,a) )
并证明其结果与您的代码相同:

>>> import itertools
>>> a = "    leading spaces"
>>> print sum( 1 for _ in itertools.takewhile(str.isspace,a) )
4
>>> print "Leading spaces", len(a) - len(a.lstrip())
Leading spaces 4

我不确定这段代码是否比您原来的解决方案更好。它的优点是不会创建更多的临时字符串,但这非常小(除非字符串非常大)。我觉得这两个版本都不清楚这一行代码的含义,所以如果您计划多次使用它(在任何情况下都有适当的注释),我肯定会将它包装在一个命名良好的函数中。

您的方式是pythonic的,但不正确,它还将计算其他空格字符,要仅计算空格,请显式
a.lstrip(“”)


使用
下一步
枚举

next((i for i, c in enumerate(a) if c != ' '), len(a))
对于任何空白:

next((i for i, c in enumerate(a) if not c.isspace()), len(a))

只是为了多样性,理论上可以使用正则表达式。它比对
len()

或者:

>>> re.search('[^ ]', a).start() # index of the first non-space char
3

但我不建议这样做;根据我做的一个快速测试,它的效率远远低于
len(a)-len(lstrip(a))

我最近做了一个类似的计算缩进的任务,因为我想将tab计算为四个空格:

def indent(string: str):
    return sum(4 if char is '\t' else 1 for char in string[:-len(string.lstrip())])

可以使用正则表达式:

def count_leading_空格:
匹配=重新搜索(r“^\s*”,s)
如果不匹配,则返回0,否则不匹配。结束()
在[17]中:计数前导空间(“asd fjk gl”)
Out[17]:4
[18]中:计数前导空格(“asd fjk gl”)
Out[18]:1
在[19]中:计数前导空间(“asd fjk gl”)
Out[19]:0

在我看来已经很像python了。不愉快但不同的方式:
a.count(“,0,a.index(a.split(None,1)[0]))
请记住,lstrip将删除制表符和其他空格字符以及空格。我正试图弄清楚这一点,只是没有itertools。我真的需要学习itertools…在我的系统上(运行在Windows上的Python 2.7.10 32位),lstrip()的速度是itertools的3.5倍。@ChaimG--我打赌我们可以构造一些并非如此的字符串(例如,如果字符串很长,只有一个或两个前导空格)。然而,对于许多常见的情况,我同意
lstrip
会快得多。@mgilson——正确。使用字符串:
a='+'a'*100000000
,itertools的速度要快67k倍。我想知道为什么?是因为lstrip()创建了字符串的副本吗?@ChaimG——这就是为什么:-)。有一次,我假设
lstrip()
不会创建一个新字符串——不变性应该使这成为可能。然而,我曾在谷歌邮件列表上发表过这样的声明,并被Alex Martelli IIRC更正:-)。我不确定他们为什么不重新使用旧字符串,但这可能是因为在很多情况下,这会阻止大型字符串被释放。
>>> re.search('[^ ]', a).start() # index of the first non-space char
3
def indent(string: str):
    return sum(4 if char is '\t' else 1 for char in string[:-len(string.lstrip())])