Objetivo: aprender a invertir secuencias en Python.
¿Cansado de que tu nombre figure siempre en las últimas páginas de las listas de resultados de exámenes? ¿No has podido renovar el DNI después de varias horas esperando en una cola? Si es así, necesitas leer este artículo cuanto antes.
Voy a mostrarte cómo invertir secuencias en Python, ponerlas patas arriba y presentarlas al revés.
Comencemos considerando una cadena de caracteres cualquiera:
>>> a = 'pradera'
La técnica para invertir secuencias se basa en los slices, que ya deben resultarte familiares si has leído los artículos anteriores.
Repasemos su sintaxis:
secuencia[i:j:k]
El primer parámetro indica el índice de comienzo del trozo y el segundo el final, pero sin incluir. El tercero es opcional y, cuando está presente, indica el incremento con el que recorreremos el camino entre el principio y el fin.
Veamos algunos ejemplos:
>>> a[0:3]
'pra'
Hemos cortado un fragmento que abarca desde el carácter que tiene por índice 0 (es decir, el primero), hasta el que tiene 3 sin incluir (esto es, hasta el índice 2).
El siguiente slice hace uso de los tres parámetros:
>>> a[1:6:2]
'rdr'
Para comprenderlo, extrae primero el fragmento que correspondería a [1:6]:
'rader'
Y ahora recorre la secuencia de dos en dos, empezando por el primero:
'rdr'
El siguiente ejemplo muestra la omisión del primer parámetro, indicando que comenzamos desde el principio:
>>> a[:4]
'prad'
O del segundo, lo que significa que sigue hasta el final:
>>> a[3:]
'dera'
O de ambos:
>>> a[:]
'pradera'
Recuerda que ya presentamos esta última técnica como método para duplicar una secuencia.
Visto este pequeño repaso, lo que nos interesa muy particularmente es el caso en el que el tercer parámetro del slice es negativo. Eso significa que el fragmento se extrae no de izquierda a derecha, sino al revés, de derecha a izquierda.
Observa el ejemplo:
>>> a[5:1:-1]
'reda'
Analicemos esto con cuidado esto para asegurarnos de que lo entendemos bien:
Lo primero que quizás te llame la atención es que el primer parámetro es mayor que el segundo. Esto es así debido a que estamos recorriendo la secuencia de derecha a izquierda. El índice de comienzo siempre será más alto (o al menos igual) que el índice de destino.
Comenzamos el corte hacia atrás desde el carácter que tiene por índice 5: ‘r’.
¿Y dónde terminamos? En el inmediatamente anterior al indicado en el segundo parámetro. Puesto que estamos recorriendo la secuencia al revés, el anterior del índice 1 no es el índice cero sino 2: ‘a’.
Y ahora sí, tomamos de derecha a izquierda todos esos caracteres, desde un extremo hasta el otro:
'reda'
Ya estás en condiciones de entender lo que hace esto:
>>> a[::-1]
'aredarp'
Es nuestro buscado string invertido.
Como no fijamos valores iniciales ni finales estamos indicando que actuaremos sobre la cadena completa.
Apréndete bien esta técnica, es el procedimiento básico para invertir secuencias, algo que tendrás que realizar con frecuencia en tu vida como programador.
Naturalmente, con las listas (un tipo de secuencias) otro tanto de lo mismo:
>>> a = [1, 2, 3]
>>> a[::-1]
[3, 2, 1]
Es muy importante que tengas siempre presente que el slicing siempre genera un objeto nuevo. Con los strings puede parecer obvio, ya que son inmutables, pero quizás no tanto con las listas, que no lo son (pueden modificarse in-situ).
Constata que la lista sigue siendo la misma:
>>> a
[1, 2, 3]
Por último, voy a enseñarte otra técnica muy útil para invertir listas, pero con la particularidad de que realizaremos una operación destructiva, modificando in-situ la lista (aprovechándonos de su mutabilidad): el método reverse().
>>> a.reverse()
>>> a
[3, 2, 1]
Observa que no ha habido creación de un duplicado, sino que el objeto original ha sido directamente modificado.
La siguiente lista muestra el resultado de una carrera entre varios colegas:
>>> clasificacion = ['Jesús', 'Pedro', 'José Luis', 'Javier']
No es que me importe particularmente quedarme el último pero, si dispongo de recursos, ¿por qué no los habría de utilizar?
>>> clasificacion.reverse()
>>> clasificacion
['Javier', 'José Luis', 'Pedro', 'Jesús']
Ni slicing ni gaitas: he preferido actuar directamente sobre el objeto, destruyendo el anterior.
Y ahora eso ya tiene otra pinta, ¿somos pythonistas o no?
Javier Montero Gabarró
El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)
El Club del Autodidacta
Consulta el índice completo de artículos relacionados con Python.