Quiero encontrar la posición (o índice) de la última ocurrencia de una cierta subcadena en la cadena de entrada str
.
Por ejemplo, supongamos que la cadena introducida es str = 'hola'
y la subcadena es target = 'l'
, entonces debería dar 3.
¿Cómo puedo hacer esto?
Usa [.rfind()
][1]:
>>> s = 'hello'
>>> s.rfind('l')
3
También no uses str
como nombre de la variable o tú'll sombrearás la [str()
][2] incorporada.
[1]: http://docs.python.org/py3k/library/stdtypes.html#str.rfind [2]: http://docs.python.org/py3k/library/functions.html#str
Puede usar rfind()
o rindex()
;
...enlaces de Python2:
rfind()
rindex()
>>> s = 'Hello StackOverflow Hi everybody'
>>> print( s.rfind('H') )
20
>>> print( s.rindex('H') )
20
>>> print( s.rfind('other') )
-1
>>> print( s.rindex('other') )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
La diferencia es que cuando no se encuentra la subcadena, rfind()
devuelve -1
mientras que rindex()
plantea una excepción ValueError
(enlace Python2:
ValueError
].
Si no quiere comprobar el código de retorno rfind()
1
, puede preferir rindex()
que proporcionará un mensaje de error comprensible.
Si no, puedes buscar los minutos en los que el valor inesperado "1" viene de tu código...
Búsqueda del último carácter de la línea nueva
>>> txt = '''first line
... second line
... third line'''
>>> txt.rfind('\n')
22
>>> txt.rindex('\n')
22
La biblioteca [más_itertools
][0] ofrece herramientas para encontrar índices de todos los caracteres o todas las sustituciones.
Dado
import more_itertools as mit
s = "hello"
pred = lambda x: x == "l"
Código
Caracteres
Ahora está disponible la herramienta [rlocate
][1c]:
next(mit.rlocate(s, pred))
# 3
Una herramienta complementaria es [localizar
][1a]:
list(mit.locate(s, pred))[-1]
# 3
mit.last(mit.locate(s, pred))
# 3
Sustratos
También hay un parámetro de "tamaño_de_ventana" disponible para localizar el artículo principal de varios artículos:
s = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?"
substring = "chuck"
pred = lambda *args: args == tuple(substring)
next(mit.rlocate(s, pred=pred, window_size=len(substring)))
# 59
[0]: https://github.com/erikrose/more-itertools [1a]: https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.locate [1c]: https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.rlocate
Si no quieres usar el [rfind][1] entonces esto funcionará.
def find_last(s, t):
last_pos = -1
while True:
pos = s.find(t, last_pos + 1)
if pos == -1:
return last_pos
else:
last_pos = pos
[1]: http://docs.python.org/py3k/library/stdtypes.html#str.rfind
No intento resucitar un puesto inactivo, pero como esto no ha sido publicado todavía...
(Así es como lo hice antes de encontrar esta pregunta)
s = "hello"
target = "l"
last_pos = len(s) - 1 - s[::-1].index(target)
Explicación:
Cuando buscas la última ocurrencia, realmente buscas la primera ocurrencia en la cadena invertida.
Sabiendo esto, hice s[::-1]
(que devuelve una cadena invertida), y luego indexé el destino
desde allí.
Luego hice "len(s) - 1 - el índice encontrado" porque queremos el índice en la cadena no invertida (es decir.
original).
¡Cuidado, sin embargo!
Si "objetivo" es más de un carácter, probablemente no lo encontrarás en la cadena invertida.
Para arreglar esto, usa last_pos = len(s) - 1 - s[::-1].index(target[::-1])
, que busca una versión invertida de target
.
puedes usar la función rindex()
para obtener la última ocurrencia de un personaje en cadena
s="hellloooloo"
b='l'
print(s.rindex(b))