如何找到字符串中前导序列的长度?

4
我想要计算字符串中前导空格的数量。最Pythonic的方法是什么?
>>>F(' ' * 5 + 'a')
5

(更新)以下是几个回答的时间表:

import timeit
>>> timeit.timeit("s.index(re.search(r'\S',s).group())", number=10000, setup="import re;s='     a'")
0.027384042739868164
>>> timeit.timeit("len([i for i in itertools.takewhile(str.isspace,s)])", number=10000, setup="import itertools;s='     a'")
0.025166034698486328
>>> timeit.timeit("next(idx for idx,val in enumerate(s) if val != ' ')", number=10000, setup="s='     a'")
0.028306961059570312
>>> timeit.timeit("F('     a')", number=10000, setup="def F(s): return len(s)-len(s.lstrip(' '))")
0.0051808357238769531

@AvinashRaj 他正在计算前导空格。 - Bhargav Rao
我认为YOU的答案是最Pythonic的,Saksham Varma的答案紧随其后;但你的结果可能会有所不同。我想最好对所提出的各种替代方案进行一些timeit测试...顺便说一句,像F这样使用大写字母作为函数名绝对不是Pythonic的做法。 :) - PM 2Ring
10个回答

7
使用 re 模块 进行操作。
>>> s
'     a'
>>> import re
>>> s.index(re.search(r'\S',s).group())
5

使用itertools模块

>>> import itertools
>>> len([i for i in itertools.takewhile(str.isspace,s)])
5

暴力破解方式
>>> def F(s):
...     for i in s:
...          if i!=' ':
...               return s.index(i)
... 
>>> F(s)
5

4
>>> F = lambda x:len(x)-len(x.lstrip(' '))
>>> F(' ' * 5 + 'a')
5

如果你需要找到前导空格的长度,你可以从lstrip中删除 ' ',因为它现在仅限于空格。

1
没有使用lambda,但如上所示,两个长度的差异似乎产生了最快的结果。 - Mark Harrison

3
def f(string):
    try:
        return [c == ' ' for c in string].index(False)
    except ValueError:
        return -1

查找第一个与' '不匹配的字符。


1
不错。except ValueError:比使用未命名的except子句要好得多。来自https://docs.python.org/3/tutorial/errors.html#handling-exceptions,“最后一个except子句可以省略异常名称,作为通配符使用。请极度小心使用此功能,因为以此方式很容易掩盖真正的编程错误!”。还可以参见https://dev59.com/AWUq5IYBdhLWcg3wF8lQ。 - PM 2Ring

3
使用enumerate遍历字符串s。一旦你遇到s中的非' '项,打印该索引,这就是你要寻找的内容。
>>> for i, val in enumerate(s):
...    if val != ' ':  
...       print i  
...       break
...
5

1

通过re模块和使用len函数。

>>> s = '     a'
>>> len(re.sub(r'\S.*', '',s))
5

这将删除从第一个非空格字符到最后一个字符之间的所有字符。然后,len函数应用于结果字符串,给出前导空格的长度。 或者
>>> s = '     a'
>>> len(re.match(r'\s*', s).group())
5
>>> s = 'a'
>>> len(re.match(r'\s*', s).group())
0

这将仅匹配零个或多个前导空格。

或者

使用 re.match 函数的 end() 属性。

>>> s = '     a'
>>> re.match(r'\s*', s).end()
5
>>> re.match(r'\s*', 'd').end()
0

感谢Adam


1

哦,还有一个没有人发布过的。

def leading_spaces(s):
    return next(idx for idx,val in enumerate(s) if val != " ")

这几乎可以肯定是最快的方法。

1
为什么一个以“哦,再来一个”的答案开头 - Bhargav Rao

0
一个简单的映射然后求和:
>>> sum(map(bool, takewhile(str.isspace, '    a  ')))
4

0

代码:

>>> i = 0
>>> while i < len(s):
...     if s[i] != ' ':
...       print i
...       break  
...     i += 1

5

0

使用第一个字符从左侧剥离字符串:

>>> s = 'aaaaabaca'
>>> len(s) - len(s.lstrip(s[0]))
5

如果您希望它能支持空字符串,请添加一个检查:
>>> s = ''
>>> len(s) - len(s.lstrip(s[0])) if s else 0
0

-2

很抱歉没有表达得够清楚...初始化一个计数器...然后遍历字符串并设置一个条件来检查列表中的每个变量是否为空格,计数器加1...

counter = 0

sstring = " " * 5 + "a"

for x in sstring:

    if x == " ":
        counter += 1
    else:
        continue

print(counter)

非常抱歉,我不知道为什么我的脚本总是以这种糟糕的格式显示...我在这里还比较新


1
@samlexxy,你需要在else块中添加break语句。尝试使用类似f = " " * 5 + "a " + " b"的字符串运行代码,你会看到结果。 - Anshul Goyal
我正在遍历字符串...一旦迭代完成,程序会自动中断...也许我理解了你的解释。 - samlexxy
2
这段代码不起作用。你应该测试 if x == " ":,而不是 f == " "。但即使这样,它也会计算 f 中的 所有 空格,而不仅仅是 前导 空格。为了解决这个问题,你需要将 continue 改为 break,就像 mu 無 解释的那样。 - PM 2Ring
我猜你是新手Python,不知道“continue”和“break”语句的区别……再读一遍问题……编写一个脚本来计算字符串开头的空格数……如果你不理解,也可以省略“else: continue”语句。 - samlexxy
1
你的代码没有找到字符串中的前导空白符,而是找到了字符串中空白符的总数。使用 sum(ch.isspace() for ch in s) 可以更容易地实现这个功能。 - Adam Smith
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接