![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Hasta este momento hemos visto tres tipos de datos: enteros, flotantes y cadenas. Las cadenas son, desde un punto de vista cualitativo, distintas de los otros dos porque éstas están compuestas de "piezas" más pequeñas caracteres.
Los tipos que constan de piezas más pequeñas se denominan tipos de datos compuestos. Dependiendo de lo que estemos haciendo, puede que queramos tratar un tipo de datos compuestos como un todo o queramos acceder a sus partes. Esta ambigüedad resulta de utilidad.
El operador corchete selecciona un carácter sencillo de una cadena.
>>> fruta = "banana"
>>> letra = fruta[1]
>>> print letra
La expresión fruta[1] selecciona el carácter número 1 de fruta. La variable letra remite al resultado. Cuando visualizamos letra, ocurre algo inesperado:
a
La primera letra de "banana" no es una a, a menos que seas informático. Por algún motivo, los informáticos siempre empiezan a contar desde cero. La "letra cero" de "banana" es b. La primera letra es a, y la segunda letra es n.
Si quieres la letra cero de una cadena, tan sólo tienes que poner 0, o cualquier expresión cuyo valor sea 0, entre corchetes:
>>> letra = fruta[0]
>>> print letra
b
La expresión entre corchetes se denomina índice. Un índice especifica un miembro de un conjunto ordenado, en este caso, el conjunto de caracteres de una cadena. El índice indica cuál quieres, de ahí su nombre. Puede ser cualquier expresión entera.
Comentarios
La función len devuelve el número de caracteres de una cadena:
>>> fruta = "banana"
>>> len(fruta)
6
Para obtener la última letra de una cadena puede que intentes hacer algo así:
longitud = len(fruta)
último = fruta[longitud] # ¡ERROR!
Eso no funciona. Esa secuencia produce un error de tiempo de ejecución IndexError: string
index out of range. El motivo es que no hay sexta letra en "banana". Ya que empezamos a contar desde cero, las seis letras se enumeran del 0 al 5. Para obtener el último carácter, tenemos que restar 1 a longitud:
longitud = len(fruta)
último = fruta[longitud-1]
Otra manera de hacerlo es usando índices negativos, que cuentan hacia atrás desde el final de la cadena. La expresión fruta[-1] obtiene la última letra, fruta[-2] obtiene la penúltima, y así sucesivamente.
Comentarios
Muchos cómputos implican procesar una cadena carácter por carácter. A menudo comienzan desde el principio, seleccionan cada carácter por turno, hacen algo con él y continúan hasta el final. Este sistema de procesamiento se denomina recorrido. Una forma de codificar un recorrido es mediante una instrucción while:
índice = 0
while índice < len(fruta):
letra = fruta[índice]
print letra
índice = índice + 1
Este bucle recorre la cadena y visualiza cada letra por sí sola. La condición del bucle es índice < len(fruta), de manera que cuando índice es igual a la longitud de la cadena, la condición es falsa y el cuerpo del bucle no se ejecuta. El último carácter al que se accede es el único con el índice len(fruta)-1, que es el último carácter de la cadena.
A modo de ejercicio, escribe una función que tome una cadena como argumento y produzca una salida de las letras hacia atrás, una por cada línea.
Utilizar un índice para recorrer un conjunto de valores es tan común que Python proporciona una alternativa, simplificar la sintaxis con el bucle for:
for char in fruta:
print char
Cada vez que pasa por el bucle, el siguiente carácter en la cadena se asigna a la variable de tipo char. El bucle continúa hasta que no queden caracteres.
El siguiente ejemplo muestra cómo usar la concatenación y un bucle for para generar una serie en abecedario. "Abecedario" hace referencia a una serie o lista en la cual los elementos aparecen por orden alfabético. Por ejemplo, en el libro de Robert McCloskey Abran paso a los patitos, los nombres de los patitos en inglés eran Jack, Kack, Lack, Mack, Nack, Ouack, Pack y Quack. Este bucle produce una salida de estos nombres en orden:
prefijos = "JKLMNOPQ"
sufijo = "ack"
for letra in prefijos:
print letra + sufijo
El resultado de este programa es:
Jack
Kack
Lack
Mack
Nack
Oack
Pack
Qack
Por supuesto, no es una clasificación del todo correcta, ya que ni "Ouack" ni "Quack" están bien escritos.
A modo de ejercicio, modifica el programa para solucionar este error.
Un trozo de una cadena se denomina segmento. Elegir un segmento es parecido a elegir un carácter:
>>> s = "Pedro, Blas, y Rosa"
>>> print s[0:5]
Pedro
>>> print s[7:11]
Pablo
>>> print s[17:21]
María
El operador [n:m] devuelve la parte de la cadena del carácter izquierdo "n" al carácter derecho "m", incluyendo el primero pero excluyendo el último. Este funcionamiento es poco intuitivo; parece más lógico si te imaginas los índices apuntando entre los caracteres, como en el siguiente diagrama:

Si omites el primer índice (antes de los dos puntos), el segmento empieza al comienzo de la cadena. Si omites el segundo índice, el segmento va al final de la cadena. Entonces:
>>> fruta = "banana"
>>> fruta[:3]
'ban'
>>> fruta[3:]
'ana'
¿Qué crees que significa s[:] ?
Comentarios
El operador de comparación funciona con cadenas. Para ver si dos cadenas son iguales:
if palabra == "banana":
print "¡No tenemos bananas!"
Otras operaciones de comparación son útiles para ordenar palabras alfabéticamente:
if palabra < "banana":
print "Tu palabra", + palabra + ", antes de banana."
elif palabra > "banana":
print "Tu palabra", + palabra + ", después de banana."
else:
print "¡No tenemos bananas!"
Sin embargo deberías ser consciente de que Python no usa las letras mayúsculas y minúsculas como nosotros. Todas las letras mayúsculas aparecen antes que las minúsculas. El resultado es el siguiente:
Tu palabra, Zebra, aparece antes que banana.
Una manera común de resolver este problema es convertir las cadenas a formato standard, como por ejemplo todas las letras en minúscula, antes de llevar a cabo la comparación. Más difícil será conseguir que el programa se de cuenta de que las zebras no son frutas.
Comentarios
Uno se siente tentado a usar el operador [] en la parte izquierda de una asignación, con la intención de cambiar un carácter en una cadena. Por ejemplo:
saludo = "¡Hola, mundo!"
saludo[0] = 'J' # ¡ERROR!
print saludo
En vez de producir la respuesta ¡Jola, mundo!, este código produce el error de ejecución TypeError: object doesn't support item
assignment.
Las cadenas son inmutables, lo que significa que no puedes cambiar ninguna cadena que ya existe. Lo mejor que puedes hacer es crear una nueva cadena que sea una variación de la original:
saludo = "Hola, mundo!"
nuevoSaludo = 'J' + saludo[1:]
print nuevoSaludo
Aquí la solución sería concatenar una primera letra nueva con un segmento de saludo. Esta operación no afecta a la cadena original.
Comentarios
¿Qué hace la siguiente función?
def hallar(str, ch):
indice = 0
while indice < len(str):
if str[indice] == ch:
return indice
indice = índice + 1
return -1
En cierta forma, hallar es lo contrario al operador []. En vez de tomar un índice y extraer el correspondiente carácter, toma un carácter y encuentra el índice donde aparece. Si el carácter no se encuentra, la función devuelve -1.
Este es el primer ejemplo que hemos visto de una instrucción return dentro de un bucle. If str[índice] == ch, la función devuelve inmediatamente, saliendo del bucle antes de tiempo.
Si el carácter no aparece en la cadena, entonces el programa cierra el bucle normal y devuelve -1.
A este elemento de programación a veces se le conoce como recorrido "eureka" porque en cuanto encontramos lo que estamos buscando, podemos gritar "eureka" y dejar de seguir buscando.
Como ejercicio, modifica la función hallar de tal manera que tome un tercer parámetro, el índice de la cadena por el que debería empezar a buscar.
El siguiente programa cuenta las veces que la letra a aparece en una cadena:
fruta = "banana"
contador = 0
for char in fruta:
if char == 'a':
contador = contador + 1
print contador
Este programa hace una demostración de otro elemento de cómputo denominado contador. La variable contador se inicia en 0 y luego se incrementa cada vez que se encuentra una a. (Incrementar significa aumentar en uno, y es lo contrario de decrementar). Cuando el bucle termina, el contador contiene el resultado es decir el número total de aes.
A modo de ejercicio, encierra este código en una función denominada contarLetras, y generalízala con el fin de que acepte la cadena y la letra como parámetros.
Como segundo ejercicio, reescribe esta función de manera que, en lugar de hacer un repaso de la cadena, use la versión de tres parámetros de hallar de la anterior.Comentarios
El módulo string contiene funciones útiles que manipulan cadenas. Como de costumbre, tenemos que importar el módulo antes de que podamos usarlo:
>>> import string
El módulo string incluye una función llamada find que hace lo mismo que la función hallar que hemos escrito. Para llamarla tenemos que especificar el nombre del módulo y el nombre de la función usando la notación de puntos.
>>> fruta = "banana"
>>> índice = string.find(fruta, "a")
>>> print índice
1
Este ejemplo demuestra uno de los beneficios de los módulos que ayudan a evitar colisiones entre los nombres de las funciones incorporadas y las definidas por el usuario. Mediante el uso de la notación de puntos podemos especificar qué versión de find es la que queremos.
En realidad, string.find es más general que nuestra versión. En primer lugar, puede hallar subcadenas, no sólo caracteres:
>>> string.find("banana", "na")
2
Además, toma un argumento adicional que especifica el índice en el que debe comenzar:
>>> string.find("banana", "na", 3)
4
O puede tomar dos argumentos adicionales que especifican una escala de índices:
>>> string.find("bob", "b", 1, 2)
-1
En este ejemplo, la búsqueda no da resultado porque la letra b no aparece en la escala de índices de 1 a 2 (sin incluir 2).
Comentarios
A menudo resulta muy práctico examinar un carácter y comprobar si es una letra mayúscula o minúscula, o si se trata de un carácter o un dígito. El módulo string proporciona algunas constantes que son útiles para estos propósitos.
La cadena string.lowercase contiene todas las letras que el sistema considera que son minúsculas. De forma similar, string.uppercase contiene todas las letras mayúsculas. Prueba lo siguiente y observa lo que obtienes:
>>> print string.lowercase
>>> print string.uppercase
>>> print string.digits
Podemos usar estas constantes y find para clasificar caracteres. Por ejemplo, si find(lowercase, ch) devuelve un valor aparte de -1, entonces ch debe ser minúscula:
def esMenor(ch):
return string.find(string.lowercase, ch) != -1
Alternativamente podemos sacar partido del operador in, que determina si un caracter aparece en una cadena:
def esMenor(ch):
return ch in string.lowercase
Aún como otra alternativa, podemos usar el operador de comparación:
def esMenor(ch):
return 'a' <= ch <= 'z'
Si ch se encuentra entre a y z, debe ser una letra minúscula.
A modo de ejercicio, analiza qué versión de esMenor crees que es la más rápida. ¿Puedes pensar en otras razones, aparte de la rapidez, para preferir una en lugar de la otra?
Otra constante definida en el módulo string puede sorprenderte cuando la imprimas:
>>> print string.whitespace
Los caracteres separadores mueven el cursor sin imprimir nada. Éstos crean el espacio en blanco entre caracteres visibles (al menos en papel blanco). La constante string.whitespace contiene todos los caracteres separadores, incluyendo el espacio, tabulador (\t), y salto de línea (\n).
Hay otras funciones útiles en el módulo string, pero este libro no pretende ser un manual de referencia. Sin embargo, la Referencia de la Biblioteca de Python sí lo es, y está disponible en la página web de Python, www.python.org, junto con gran cantidad de documentación complementaria.
Comentarios
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |