在 Python 中执行此操作的最短方法是什么?
string = " xyz"
必须返回索引 = 3
>>> s = " xyz"
>>> len(s) - len(s.lstrip())
3
>>> next(i for i, j in enumerate(' xyz') if j.strip())
3
或者
>>> next(i for i, j in enumerate(' xyz') if j not in string.whitespace)
3
在 Python < 2.5 的版本中,您必须执行以下操作:
(...).next()
许多先前的解决方案在他们提出的解决方案中的几个点上进行迭代。有些人会复制数据(字符串)。re.match()、strip()、enumerate()、isspace() 在幕后重复工作。这
next(idx for idx, chr in enumerate(string) if not chr.isspace())
next(idx for idx, chr in enumerate(string) if not chr.whitespace)
是针对各种领先的空白类型(例如垂直制表符等)测试字符串的不错选择,但这也增加了成本。
但是,如果您的字符串仅使用空格字符或制表符,那么以下更基本的解决方案、清晰快速的解决方案也使用更少的内存。
def get_indent(astr):
"""Return index of first non-space character of a sequence else False."""
try:
iter(astr)
except:
raise
# OR for not raising exceptions at all
# if hasattr(astr,'__getitem__): return False
idx = 0
while idx < len(astr) and astr[idx] == ' ':
idx += 1
if astr[0] <> ' ':
return False
return idx
尽管这在视觉上可能不是绝对最快或最简单的,但此解决方案的一些好处是您可以轻松地将其转移到其他语言和 Python 版本。并且可能是最容易调试的,因为几乎没有魔术行为。如果您将函数的内容与代码内联而不是放在函数中,您将删除函数调用部分,并使该解决方案在字节码中与其他解决方案相似。
此外,此解决方案允许更多变化。例如为标签添加测试
or astr[idx] == '\t':
或者您可以将整个数据测试为可迭代一次,而不是检查每一行是否可迭代。记住像 ""[0] 会引发异常,而 ""[0:] 不会。
如果您想将解决方案推送到内联,您可以采用非 Pythonic 路线:
i = 0
while i < len(s) and s[i] == ' ': i += 1
print i
3
. .
看起来“正则表达式可以做任何事情”大队已经休息了一天,所以我将填写:
>>> tests = [u'foo', u' foo', u'\xA0foo']
>>> import re
>>> for test in tests:
... print len(re.match(r"\s*", test, re.UNICODE).group(0))
...
0
1
1
>>>
FWIW:花费的时间是 O(the_answer),而不是 O(len(input_string))
import re
def prefix_length(s):
m = re.match('(\s+)', s)
if m:
return len(m.group(0))
return 0
>>> string = " xyz"
>>> map(str.isspace,string).index(False)
3
>>> string = " xyz"
>>> next(idx for idx, chr in enumerate(string) if not chr.isspace())
3