Comprobar si una cadena comienza con XXXX

Resuelto John Marston asked hace 12 años • 6 respuestas

Me gustaría saber cómo comprobar si una cadena comienza con "hola" en Python.

En Bash suelo hacer:

if [[ "$string" =~ ^hello ]]; then
 do something here
fi

¿Cómo logro lo mismo en Python?

John Marston avatar Jan 10 '12 18:01 John Marston
Aceptado
aString = "hello world"
aString.startswith("hello")

Más información sobre startswith.

RanRag avatar Jan 10 '2012 11:01 RanRag

RanRag ya respondió a su pregunta específica.

Sin embargo, en términos más generales, lo que estás haciendo con

if [[ "$string" =~ ^hello ]]

es una coincidencia de expresiones regulares . Para hacer lo mismo en Python, harías:

import re
if re.match(r'^hello', somestring):
    # do stuff

Evidentemente, en este caso, somestring.startswith('hello')es mejor.

Shawabawa avatar Jan 10 '2012 12:01 Shawabawa

En caso de que desee hacer coincidir varias palabras con su palabra mágica, puede pasar las palabras para que coincidan como una tupla:

>>> magicWord = 'zzzTest'
>>> magicWord.startswith(('zzz', 'yyy', 'rrr'))
True

startswithtoma una cadena o una tupla de cadenas.

user1767754 avatar Nov 10 '2017 19:11 user1767754

También se puede hacer de esta manera..

regex=re.compile('^hello')

## THIS WAY YOU CAN CHECK FOR MULTIPLE STRINGS
## LIKE
## regex=re.compile('^hello|^john|^world')

if re.match(regex, somestring):
    print("Yes")
Aseem Yadav avatar Sep 24 '2016 10:09 Aseem Yadav

Hice un pequeño experimento para ver cuál de estos métodos

  • string.startswith('hello')
  • string.rfind('hello') == 0
  • string.rpartition('hello')[0] == ''
  • string.rindex('hello') == 0

son más eficientes para devolver si una determinada cadena comienza con otra cadena.

Este es el resultado de una de las muchas ejecuciones de prueba que he realizado, donde cada lista está ordenada para mostrar el menor tiempo que tomó (en segundos) analizar 5 millones de cada una de las expresiones anteriores durante cada iteración del whileciclo que usé. :

['startswith: 1.37', 'rpartition: 1.38', 'rfind: 1.62', 'rindex: 1.62']
['startswith: 1.28', 'rpartition: 1.44', 'rindex: 1.67', 'rfind: 1.68']
['startswith: 1.29', 'rpartition: 1.42', 'rindex: 1.63', 'rfind: 1.64']
['startswith: 1.28', 'rpartition: 1.43', 'rindex: 1.61', 'rfind: 1.62']
['rpartition: 1.48', 'startswith: 1.48', 'rfind: 1.62', 'rindex: 1.67']
['startswith: 1.34', 'rpartition: 1.43', 'rfind: 1.64', 'rindex: 1.64']
['startswith: 1.36', 'rpartition: 1.44', 'rindex: 1.61', 'rfind: 1.63']
['startswith: 1.29', 'rpartition: 1.37', 'rindex: 1.64', 'rfind: 1.67']
['startswith: 1.34', 'rpartition: 1.44', 'rfind: 1.66', 'rindex: 1.68']
['startswith: 1.44', 'rpartition: 1.41', 'rindex: 1.61', 'rfind: 2.24']
['startswith: 1.34', 'rpartition: 1.45', 'rindex: 1.62', 'rfind: 1.67']
['startswith: 1.34', 'rpartition: 1.38', 'rindex: 1.67', 'rfind: 1.74']
['rpartition: 1.37', 'startswith: 1.38', 'rfind: 1.61', 'rindex: 1.64']
['startswith: 1.32', 'rpartition: 1.39', 'rfind: 1.64', 'rindex: 1.61']
['rpartition: 1.35', 'startswith: 1.36', 'rfind: 1.63', 'rindex: 1.67']
['startswith: 1.29', 'rpartition: 1.36', 'rfind: 1.65', 'rindex: 1.84']
['startswith: 1.41', 'rpartition: 1.44', 'rfind: 1.63', 'rindex: 1.71']
['startswith: 1.34', 'rpartition: 1.46', 'rindex: 1.66', 'rfind: 1.74']
['startswith: 1.32', 'rpartition: 1.46', 'rfind: 1.64', 'rindex: 1.74']
['startswith: 1.38', 'rpartition: 1.48', 'rfind: 1.68', 'rindex: 1.68']
['startswith: 1.35', 'rpartition: 1.42', 'rfind: 1.63', 'rindex: 1.68']
['startswith: 1.32', 'rpartition: 1.46', 'rfind: 1.65', 'rindex: 1.75']
['startswith: 1.37', 'rpartition: 1.46', 'rfind: 1.74', 'rindex: 1.75']
['startswith: 1.31', 'rpartition: 1.48', 'rfind: 1.67', 'rindex: 1.74']
['startswith: 1.44', 'rpartition: 1.46', 'rindex: 1.69', 'rfind: 1.74']
['startswith: 1.44', 'rpartition: 1.42', 'rfind: 1.65', 'rindex: 1.65']
['startswith: 1.36', 'rpartition: 1.44', 'rfind: 1.64', 'rindex: 1.74']
['startswith: 1.34', 'rpartition: 1.46', 'rfind: 1.61', 'rindex: 1.74']
['startswith: 1.35', 'rpartition: 1.56', 'rfind: 1.68', 'rindex: 1.69']
['startswith: 1.32', 'rpartition: 1.48', 'rindex: 1.64', 'rfind: 1.65']
['startswith: 1.28', 'rpartition: 1.43', 'rfind: 1.59', 'rindex: 1.66']

Creo que es bastante obvio desde el principio que el startswithmétodo sería el más eficiente, ya que su objetivo principal es devolver si una cadena comienza con la cadena especificada.

Lo que me sorprende es que el string.rpartition('hello')[0] == ''método aparentemente poco práctico siempre encuentra la manera de aparecer primero, antes del string.startswith('hello')método, de vez en cuando. Los resultados muestran que usar str.partitionpara determinar si una cadena comienza con otra cadena es más eficiente que usar ambos rfindy rindex.

Otra cosa que he notado es que string.rfind('hello') == 0tenemos string.rindex('hello') == 0una buena batalla, cada uno subiendo del cuarto al tercer lugar y bajando del tercero al cuarto, lo cual tiene sentido, ya que sus propósitos principales son los mismos.

Aquí está el código:

from time import perf_counter

string = 'hello world'
places = dict()

while True:
    start = perf_counter()
    for _ in range(5000000):
        string.startswith('hello')
    end = perf_counter()
    places['startswith'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rfind('hello') == 0
    end = perf_counter()
    places['rfind'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rpartition('hello')[0] == ''
    end = perf_counter()
    places['rpartition'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rindex('hello') == 0
    end = perf_counter()
    places['rindex'] = round(end - start, 2)
    
    print([f'{b}: {str(a).ljust(4, "4")}' for a, b in sorted(i[::-1] for i in places.items())])
Red avatar Nov 30 '2020 19:11 Red