Подтвердить что ты не робот

Что такое pythonic способ подсчета ведущих пробелов в строке?

Я знаю, что могу подсчитать ведущие пробелы в строке с помощью этого:

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

Но есть ли более питонический путь?

4b9b3361

Ответ 1

Ваш путь является питоническим, но неправильным, он также учитывает другие символы пробелов, чтобы считать только пробелы явными a.lstrip(' '):

a = "   \r\t\n\tfoo bar baz qua   \n"
print "Leading spaces", len(a) - len(a.lstrip())
>>> Leading spaces 7
print "Leading spaces", len(a) - len(a.lstrip(' '))
>>> Leading spaces 3

Ответ 2

Вы можете использовать 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

Я не уверен, действительно ли этот код лучше вашего оригинального решения. Преимущество состоит в том, что он не создает более временных строк, но довольно минорный (если строки не очень большие). Я не нахожу, что любая версия будет немедленно понятна о том, что делает строка кода, поэтому я бы определенно перевернул ее в красиво названную функцию, если вы планируете использовать ее более одного раза (с соответствующими комментариями в любом случае).

Ответ 3

Просто для разнообразия можно теоретически использовать регулярное выражение. Это немного короче и выглядит лучше, чем двойной вызов len().

>>> import re
>>> a = "   foo bar baz qua   \n"
>>> re.search('\S', a).start() # index of the first non-whitespace char
3

Или, альтернативно:

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

Но я не рекомендую это; по быстрому тесту я сделал это гораздо менее эффективно, чем len(a)-len(lstrip(a)).

Ответ 4

Это выглядит... здорово для меня. Обычно я отвечаю: "Является ли X Pythonic?" вопросы с некоторой функциональной магией, но я не считаю, что подход подходит для манипуляции строкой.

Если бы существовал встроенный, чтобы возвращать только начальные пробелы, а взять len(), я бы сказал, для этого нужно, но AFAIK там нет, а re и другие решения абсолютно перехитрить.

Ответ 5

Используя next и enumerate:

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

Ответ 6

Недавно у меня была похожая задача подсчета отступов, из-за чего я хотел считать табуляцию четырьмя пробелами:

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