Насколько хорошо начинается с? - PullRequest
15 голосов
/ 22 августа 2009

Is

text.startswith('a')  

лучше чем

text[0]=='a'  

Знание текста не является пустым, и нас интересует только его первый символ.

Ответы [ 9 ]

30 голосов
/ 22 августа 2009

text[0] терпит неудачу, если text является пустой строкой:

IronPython 2.6 Alpha (2.6.0.1) on .NET 4.0.20506.1
Type "help", "copyright", "credits" or "license" for more information.
>>> text = ""
>>> print(text.startswith("a"))
False
>>> print(text[0]=='a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: index out of range: 0

РЕДАКТИРОВАТЬ: Вы говорите, что вы «знаете», что text не пусто ... насколько вы уверены в этом, и что бы вы хотели, если бы оно пусто в реальности? Если произошел сбой (например, это означает ошибку в вашем коде), который поощрил бы использование text[0]=='a'.

Другие вопросы:

  • Насколько вы обеспокоены выполнением этого? Если это критично для производительности, тогда сравните его в вашей конкретной среде исполнения Python . Я не был бы полностью удивлен, обнаружив, что (скажем) одна форма была быстрее на IronPython, а другая быстрее на CPython.

  • Что вы (и ваша команда) находите более читабельным?

23 голосов
/ 22 августа 2009

Я бы согласился с остальными, что начинается с более удобочитаемого текста, и вы должны это использовать. Тем не менее, если производительность является большой проблемой для такого особого случая, отметьте ее:

$ python -m timeit -s 'text="foo"' 'text.startswith("a")'
1000000 loops, best of 3: 0.537 usec per loop

$ python -m timeit -s 'text="foo"' 'text[0]=="a"'
1000000 loops, best of 3: 0.22 usec per loop

Так что text[0] почти в 2,5 раза быстрее - но это довольно быстрая операция; вы сэкономите ~ 0,3 микросекунды на сравнение в зависимости от системы. Если, конечно, вы не проводите миллионы сравнений в критической по времени ситуации, я бы по-прежнему использовал более читаемые старты с

10 голосов
/ 22 августа 2009

Да: его легче использовать и легче читать. Когда вы тестируете более одной буквы, при использовании нарезки вы должны знать, как долго будет целевой текст:

haystack = 'Hello, World!'
needle = 'Hello'

# The easy way
result = haystack.startswith(needle)

# The slightly harder way
result = haystack[:len(needle)] == needle

Редактировать: Вопрос, похоже, изменился. Теперь в нем говорится: «Знание текста не является пустым, и нас интересует только его первый символ». Это превращает его в довольно бессмысленную гипотетическую ситуацию.

Я подозреваю, что спрашивающий пытается «оптимизировать» его / ее код для скорости выполнения. Если это так, мой ответ: не надо. Используйте любую форму, более удобочитаемую и, следовательно, более удобную для сопровождения, когда вам придется вернуться и работать над ней через год. Оптимизируйте только, если профилирование показывает, что эта строка кода является узким местом. Это не какой-то алгоритм O (n²). Это сравнение строк.

10 голосов
/ 22 августа 2009

Лично я бы сказал, что startswith более читабельно.

Также из Python 2.5 startwith можно взять набор префиксов для поиска:

>>> "hello world".startswith(("hello","goodbye"))
True
8 голосов
/ 27 августа 2009

PEP 8 явно указывает на использование startswith из-за читабельности:

- Use ''.startswith() and ''.endswith() instead of string

нарезка для проверки для префиксов или суффиксов.

  startswith() and endswith() are cleaner and less error prone.  For
  example:

    Yes: if foo.startswith('bar'):

    No:  if foo[:3] == 'bar':
5 голосов
/ 22 августа 2009

text[0] может дать сбой, но эквивалент text[:1] безопасен, если строка пуста.

Если вы хотите сравнить более одного символа, я считаю, .startswith() лучше.

5 голосов
/ 22 августа 2009

Фраза для вопроса: «Преждевременная оптимизация - корень всего зла».

2 голосов
/ 18 сентября 2013
def compo2():
    n = "abba"
    for i in range(1000000):
        n[:1]=="_"

быстрее

def compo():
    n = "abba"
    for i in range(1000000):
        n.startswith("_")

cProfile сообщает 0.061 для compo2 по сравнению с 0.954 для compo на моей машине. Это интересно, если вы хотите сделать МНОГО проверок префиксов для различных «_mystring». Если большинство строк не начинаются с подчеркиваний, то использование string[:1]== char перед использованием startswith - это вариант для оптимизации вашего кода. В реальном приложении этот метод сэкономил мне около 15% времени процессора.

1 голос
/ 22 августа 2009

текст [0] == «а» хорошо, учитывая производительность. Также вам нужно добавить проверку при использовании этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...