Cesar Systems

Herramientas Informaticas

Cadenas

7.1. Un tipo de datos compuesto

Hasta el momento hemos visto tres tipos: int, float, y string. Las cadenas son cuantitativamente diferentes de los otros dos porque están hechas de piezas menores: caracteres.

Los tipos que comprenden piezas menores se llaman tipos de datos compuestos. Dependiendo de que estemos haciendo, podemos querer tratar un tipo compuesto como una única cosa o acceder a sus partes. Esta ambigüedad es útil.

El operador corchete selecciona un carácter suelto de una cadena.

   1: >>> fruta = "banana"

   2: >>> letra = fruta[1]

   3: >>> 

   4: print letra

La expresion fruta[1] selecciona el caracter numero 1 de fruta. La variable letra apunta al resultado. Cuando mostramos letra, nos encontramos con una sorpresa: a

La primera letra de “banana” no es a. A no ser que usted sea un programador.

Por perversas razones, los científicos de la computacion siempre empiezan a contar desde cero. La 0-sima letra (“cerosima”) de “banana” es b. La 1-esima (“unesima”) es a, y la 2-esima (dosesima”) letra es n.

Si quiera la cerosima letra de una cadena, simplemente pone 0, o cualquier expresión de valor 0, entre los corchetes:

   1: >>> letra = fruta[0]

   2: >>> print letra

   3: b

A la expresion entre corchetes se le llama índice. Un índice identifica a un miembro de un conjunto ordenado, en este caso el conjunto de caracteres de la cadena. El ³ndice indica cual quiere usted, de ahí el nombre. Puede ser cualquier expresión entera.

7.2. Longitud

La función len devuelve el número de caracteres de una cadena:

   1: >>> fruta = "banana"

   2: >>> len(fruta)

   3: 6

Para obtener la última letra de una cadena puede sentirse tentado a probar algo como esto:

   1: longitud = len(fruta)

   2: ultima = fruta[longitud] # ERROR!

Eso no funcionara. Provoca un error en tiempo de ejecucion IndexError:string index out of range. La razon es que no hay una sexta letra en “banana“. Como empezamos a contar por cero, las seis letras estan numeradas del 0 al 5. Para obtener el ultimo caracter tenemos que restar 1 de longitud:

   1: longitud = len(fruta)

   2: ultima = fruta[longitud-1]

De forma alternativa, podemos usar índices negativos, que cuentan hacia atrás desde el final de la cadena. La expresion fruta[-1] nos da la ultima letra. fruta[-2] nos da la penultima, y así.

7.3. Recorrido y el bucle for

Muchos cálculos incluyen el proceso de una cadena carácter a carácter. A menudo empiezan por el principio, seleccionan cada carácter por turno, hacen algo con el y siguen hasta el final. Este patrón de proceso se llama recorrido. Una forma de codificar un recorrido es una sentencia while:

   1: indice = 0

   2: while indice < len(fruta):

   3:     letra = fruta[indice]

   4:     print 

   5:     letra

   6:     indice = indice + 1

Este bucle recorre la cadena y muestra cada letra en una línea distinta. La condición del bucle es indice < len(fruta), de modo que cuando indice es igual a la longitud de la cadena, la condicion es falsa y no se ejecuta el cuerpo del bucle. El ultimo caracter al que se accede es el que tiene el índice len(fruta)-1, que es el ultimo caracter de la cadena.

Como ejercicio, escriba una función que tome una cadena como argumento y entregue las letras en orden inverso, una por línea.

Es tan habitual usar un índice para recorrer un conjunto de valores que Python facilita una sintaxis alternativa mas simple: el bucle for:

   1: for car in fruta:

   2: print car

Cada vez que recorremos el bucle, se asigna a la variable car el siguiente carácter de la cadena. El bucle continua hasta que no quedan caracteres.

El ejemplo siguiente muestra como usar la concatenacion junto a un bucle for para generar una serie abecedarica. “Abecedarica” es la serie o lista en la que cada uno de los elementos aparece en orden alfabetico. Por ejemplo, en el libro de Robert McCloskey Make Way for Ducklings (Dejad paso a los patitos), los nombres de los patitos son Jack, Kack, Lack, Mack, Nack, Ouack, Pack, y Quack.

Este bucle saca esos nombres en orden:

   1: prefijos = "JKLMNOPQ"

   2: sufijo = "ack"

   3: for letra in prefijos:

   4: print letra 

   5: + sufijo

   6: La salida del programa 

   7: es:

   8: Jack

   9: Kack

  10: Lack

  11: Mack

  12: Nack

  13: Oack

  14: Pack

  15: Qack

Por supuesto, esto no es del todo correcto, porque “Ouack” y “Quack” no están correctamente escritos.

Como ejercicio, modifique el programa para corregir este error.

7.4. Porciones de cadenas

Llamamos porción a un segmento de una cadena. La selección de una porción es similar a la selección de un carácter:

   1: >>> s = "Pedro, Pablo, y María"

   2: >>> print 

   3: s[0:5]

   4: Pedro

   5: >>> print s[7:12]

   6: Pablo

   7: >>> print 

   8: s[15:20]

   9: María

El operador [n:m] devuelve la parte de la cadena desde el enésimo carácter hasta el “enésimo”, incluyendo el primero pero excluyendo el ultimo. Este comportamiento contradice a nuestra intuicion; tiene mas sentido si imagina los índices se~nalando entre los caracteres, como en el siguiente diagrama:

Sin título

Si omite el primer índice (antes de los dos puntos), la porcion comienza al principio de la cadena. Si omite el segundo índice, la porcion llega al final de la cadena. Así:

   1: >>> fruta = "banana"

   2: >>> fruta[:3]

   3: 'ban'

   4: >>> 

   5: fruta[3:]

   6: 'ana'

¿Que cree usted que significa s[:]?

7.5. Comparación de cadenas

Los operadores de comparación trabajan sobre cadenas. Para ver si dos cadenas son iguales:

   1: if palabra == "banana":

   2: print "S³, no tenemos bananas!"

Otras operaciones de comparacion son utiles para poner palabras en orden alfabético:

   1: if palabra < "banana":

   2:     print "Tu palabra," + palabra + ", va antes de banana."

   3: elif palabra > "banana":

   4:     print "Tu palabra," + palabra + ", va despues de banana."

   5: else:

   6:     print "Sí, no tenemos bananas!"

Sin embargo, deber³a usted ser consciente de que Python no maneja las mayúsculas y minusculas como lo hace la gente. Todas las mayusuculas van antes de la minúsculas. Como resultado de ello:

Tu palabra, Zapato, va antes de banana.

Una forma comun de abordar este problema es convertir las cadenas a un formato estandar, como pueden ser las minusculas, antes de realizar la comparacion.

Un problema mayor es hacer que el programa se de cuenta de que los zapatos no son frutas.

7.6. Las cadenas son inmutables

Es tentador usar el operador [] en el lado izquierdo de una asignación, con la intención de cambiar un carácter en una cadena. Por ejemplo:

   1: saludo = "Hola, mundo"

   2: saludo[0] = 'M' # ERROR!

   3: print saludo

En lugar de presentar la salida Mola, mundo, este codigo presenta el siguiente error en tiempo de ejecucion TypeError: object doesn’t

   1: support item

   2: assignment.

Las cadenas son inmutables, lo que signi¯ca que no puede cambiar una cadena existente. Lo mas que puede hacer es crear una nueva cadena que sea una variacion de la original:

   1: saludo = "Hola, mundo"

   2: nuevoSaludo = 'M' + saludo[1:]

   3: print nuevoSaludo 

Aquí la solución es concatenar una nueva primera letra a una porción de saludo.

Esta operación no tiene efectos sobre la cadena original.

7.8. Bucles y conteo

El programa que sigue cuenta el numero de veces que la letra a aparece en una
cadena:

   1: fruta = "banana"

   2: cuenta = 0

   3: for car in fruta:

   4: if car == 'a':

   5: cuenta 

   6: = cuenta + 1

   7: print cuenta

Este programa muestra otro patron de computacion llamado contador. La variable cuenta se incializa a 0 y luego se incrementa cada vez que se encuentra una a. (Incrementar es aumentar en uno; es lo contario de decrementar, y sin relacion alguna con “excremento”, que es un nombre.) Al salir del bucle, cuenta contiene el resultado – el numero total de aes.

Como ejercicio, encapsule este codigo en una funcion llamada cuentaLetras, y generalícela de forma que acepte la cadena y la letra como parametros.

Como un segundo ejercicio, reescriba esta funcion para que en lugar de recorrer la cadena, use la version de tres parametros de encuentra del anterior.

7.9. El módulo “string”

El modulo string contiene funciones útiles para manipular cadenas. Como es habitual, tenemos que importar el modulo antes de poder usarlo:

   1: >>> import string

El modulo string incluye una funcion llamada find que hace lo mismo que la función encuentra que escribimos. Para llamarla debemos especificar el nombre del modulo y el nombre de la funcion por medio de la notacion de punto.

   1: >>> fruta = "banana"

   2: >>> indice = string.find(fruta, 

   3: "a")

   4: >>> print indice

   5: 1

Este ejemplo demuestra uno de los beneficios de los modulos: ayudan a evitar las colisiones entre los nombres de las funciones predefinidas y las definidas por el usuario. Al usar la notacion de punto podríamos especificar que version de find queremos en caso de haberle daddo un nombre en ingles a nuestra funcion.

En realidad, string.find es mas general que nuestra version. Para empezar, puede encontrar subcadenas, no solo caracteres:

   1: >>> string.find("banana", "na")

   2: 2

Además, acepta un argumento adicional que especifica el índice en el que debería comenzar:

   1: >>> string.find("banana", "na", 3)

   2: 4

O puede tomar dos argumentos adicionales que especifican un intervalo de índices:

   1: >>> string.find("sus", "s", 1, 2)

   2: -1

En este ejemplo, la busqueda falla porque la letra s no aparece en el intervalo de índices desde 1 hasta 2 (sin incluir 2).

7.10. Clasificación de caracteres

A menudo viene bien examinar un carácter y comprobar si es una letra mayúscula o minúscula, o si es un carácter o un dígito. El modulo string proporciona varias constantes que son útiles para estos menesteres.

La cadena string.lowercase contiene todas las letras que el sistema considera como minúsculas. De forma similar, string.uppercase contiene todas las mayúsculas. Pruebe lo que sigue y vea que obtiene:

   1: >>> print string.lowercase

   2: >>> print 

   3: string.uppercase

   4: >>> print string.digits

Podemos usar estas constantes y find para clasificar caracteres. Por ejemplo, si find(lowercase, c) devuelve un valor que no sea -1, entonces c es una minúscula:

   1: def esMinuscula(c):

   2:     return find(string.lowercase, c) != -1

Alternativamente, podemos aprovecharnos del operador in, que determina si un carácter aparece en una cadena:

   1: def esMinuscula(c):

   2:     return c in string.lowercase

Como una alternativa mas, podemos usar el operador de comparacion, aunque esta solucion solo sea practica para el alfabeto ingles:

   1: def esMinuscula(c):

   2:     return 'a' <= c <= 'z'

Si c esta entre a y z, tiene que ser una minuscula.

Como ejercicio, explique que versión de esMinuscula cree que es mas rápida. ¿Puede pensar en otras razones aparte de la velocidad para preferir una sobre la otra?

Otra constante definida en el modulo string puede sorprenderle cuando la imprima:

   1: >>> print string.whitespace

Los caracteres de whitespace mueven el cursor sin imprimir nada. Crean los espacios en blanco entre los caracteres visibles (al menos sobre papel blanco).

La constante string.whitespace contiene todos los caracteres de espacio en blanco, incluidos espacio, tabulador (t), y salto de línea (n).

Hay otras funciones útiles en el modulo string, pero este libro no pretende ser un manual de referencia. Por otra parte, la

Referencia de la Biblioteca de Python sí lo es. Junto con un montón mas de documentación, esta disponible en el sitio
web de Python, www.python.org

7.11. Glosario

tipo de datos compuesto: Un tipo de datos en el que los valores están hechos de componentes o elementos que son a su vez valores.

recorrer: Realizar de forma iterativa una operación similar sobre cada uno de los elementos de un conjunto.

índice: Una variable o valor usado para seleccionar un miembro de un conjunto ordenado, como puede ser un carácter de una cadena.

porción: Una parte de una cadena especificada por un intervalo de índices.

mutable: Un tipo de datos compuesto a cuyos elementos se les puede asignar nuevos valores.

contador: Una variable usada para contar algo, normalmente inicializado a cero e incrementado posteriormente.

Página 113 de 143

Creado con WordPress & Tema de Anders Norén