Next Up Previous Hi Index

Chapter 7

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 qu� 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.

>>> fruta = "banana"
>>> letra = fruta[1]
>>> print letra

La expresi�n fruta[1] selecciona el car�cter n�mero 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 computaci�n siempre empiezan a contar desde cero. La 0-sima letra ("cer�sima") de "banana"es b. La 1-�sima ("un�sima") es a, y la 2-�sima ("dos�sima") letra es n.

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

>>> letra = fruta[0]
>>> print letra
b

A la expresi�n 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 cu�l 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:

>>> fruta = "banana"
>>> len(fruta)
6

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

longitud = len(fruta)
ultima = fruta[longitud]       # ERROR!

Eso no funcionar�. Provoca un error en tiempo de ejecuci�n IndexError:
string index out of range
. La raz�n es que no hay una sexta letra en "banana". Como empezamos a contar por cero, las seis letras est�n numeradas del 0 al 5. Para obtener el �ltimo car�cter tenemos que restar 1 de longitud:

longitud = len(fruta)
ultima = fruta[longitud-1]

De forma alternativa, podemos usar �ndices negativos, que cuentan hacia atr�s desde el final de la cadena. La expresi�n fruta[-1] nos da la �ltima letra. fruta[-2] nos da la pen�ltima, y as�.

7.3 Recorrido y el bucle \tt{for

\label{for} \index{recorrido} \index{bucle!recorrido} \index{bucle for} \index{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 �l y siguen hasta el final. Este patr�n de proceso se llama {\bf recorrido}. Una forma de codificar un recorrido es una sentencia \verb|while|: \adjustpage{2} \beforeverb \begin{verbatim} indice = 0 while indice < len(fruta): letra = fruta[indice] print letra indice = indice + 1 \end{verbatim} \afterverb % Este bucle recorre la cadena y muestra cada letra en una l�nea distinta. La condici�n del bucle es \verb|indice < len(fruta)|, de modo que cuando \verb|indice| es igual a la longitud de la cadena, la condici�n es falsa y no se ejecuta el cuerpo del bucle. El �ltimo car�cter al que se accede es el que tiene el �ndice \verb|len(fruta)-1|, que es el �ltimo car�cter de la cadena. \begin{quote} {\em Como ejercicio, escriba una funci�n que tome una cadena como argumento y entregue las letras en orden inverso, una por l�nea.} \end{quote} Es tan habitual usar un �ndice para recorrer un conjunto de valores que Python facilita una sintaxis alternativa m�s simple: el bucle \verb|for|: \beforeverb \begin{verbatim} for car in fruta: print car \end{verbatim} \afterverb % Cada vez que recorremos el bucle, se asigna a la variable \verb|car| el siguiente car�cter de la cadena. El bucle contin�a hasta que no quedan caracteres. \index{concatenaci�n} \index{abeced'arico} \index{McCloskey, Robert} \index{{\em Make Way for Ducklings}} El ejemplo siguiente muestra c�mo usar la concatenaci�n junto a un bucle {\tt for} para generar una serie abeced�rica. ``Abeced�rica'' es la serie o lista en la que cada uno de los elementos aparece en orden alfab�tico. Por ejemplo, en el libro de Robert McCloskey {\em 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: \beforeverb \begin{verbatim} prefijos = "JKLMNOPQ" sufijo = "ack" for letra in prefijos: print letra + sufijo \end{verbatim} \afterverb % La salida del programa es: \beforeverb \begin{verbatim} Jack Kack Lack Mack Nack Oack Pack Qack \end{verbatim} \afterverb % Por supuesto, esto no es del todo correcto, porque ``Ouack'' y ``Quack'' no est�n correctamente escritos. \begin{quote} {\em Como ejercicio, modifique el programa para corregir este error.} \end{quote} \section{Porciones de cadenas} \label{slice} \index{porci�n} \index{cadena!porci�n} Llamamos {\bf 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: \beforeverb \begin{verbatim} >>> s = "Pedro, Pablo, y Mar�a" >>> print s[0:5] Pedro >>> print s[7:12] Pablo >>> print s[15:20] Mar�a \end{verbatim} \afterverb % El operador \verb|[n:m]| devuelve la parte de la cadena desde el en�simo car�cter hasta el ``em�simo'', incluyendo el primero pero excluyendo el �ltimo. Este comportamiento contradice a nuestra intuici�n; tiene m�s sentido si imagina los �ndices se�alando {\em entre} los caracteres, como en el siguiente diagrama: \beforefig \centerline{\psfig{figure=../illustrations/banana.eps}} \afterfig Si omite el primer �ndice (antes de los dos puntos), la porci�n comienza al principio de la cadena. Si omite el segundo �ndice, la porci�n llega al final de la cadena. As�: \beforeverb \begin{verbatim} >>> fruta = "banana" >>> fruta[:3] 'ban' >>> fruta[3:] 'ana' \end{verbatim} \afterverb % �Qu� cree usted que significa \verb|s[:]|? \section{Comparaci�n de cadenas} \index{comparaci�n de cadenas} \index{comparaci�n!cadenas} Los operadores de comparaci�n trabajan sobre cadenas. Para ver si dos cadenas son iguales: \beforeverb \begin{verbatim} if palabra == "banana": print "S�, no tenemos bananas!" \end{verbatim} \afterverb % \adjustpage{-2} Otras operaciones de comparaci�n son �tiles para poner palabras en orden alfab�tico: \beforeverb \begin{verbatim} if palabra < "banana": print "Tu palabra," + palabra + ", va antes de banana." elif palabra > "banana": print "Tu palabra," + palabra + ", va despu�s de banana." else: print "S�, no tenemos bananas!" \end{verbatim} \afterverb % Sin embargo, deber�a usted ser consciente de que Python no maneja las may�sculas y min�sculas como lo hace la gente. Todas las may�suculas van antes de la min�sculas. Como resultado de ello: \beforeverb \begin{verbatim} Tu palabra, Zapato, va antes de banana. \end{verbatim} \afterverb % Una forma com�n de abordar este problema es convertir las cadenas a un formato est�ndar, como pueden ser las min�sculas, antes de realizar la comparaci�n. Un problema mayor es hacer que el programa se d� cuenta de que los zapatos no son frutas. \section{Las cadenas son inmutables} \index{mutable} \index{cadena inmutable} \index{cadena!inmutable} Es tentador usar el operador \verb|[]| en el lado izquierdo de una asignaci�n, con la intenci�n de cambiar un car�cter en una cadena. Por ejemplo: \beforeverb \begin{verbatim} saludo = "Hola, mundo" saludo[0] = 'M' # ERROR! print saludo \end{verbatim} \afterverb % En lugar de presentar la salida \verb|Mola, mundo|, este c�digo presenta el siguiente error en tiempo de ejecuci�n {\tt TypeError: object doesn't support item assignment}. \index{error en tiempo de ejecuci�n} Las cadenas son {\bf inmutables}, lo que significa que no puede cambiar una cadena existente. Lo m�s que puede hacer es crear una nueva cadena que sea una variaci�n de la original: \beforeverb \begin{verbatim} saludo = "Hola, mundo" nuevoSaludo = 'M' + saludo[1:] print nuevoSaludo \end{verbatim} \afterverb % Aqu� la soluci�n es concatenar una nueva primera letra a una porci�n de \verb|saludo|. Esta operaci�n no tiene efectos sobre la cadena original. \index{concatenaci�n} \adjustpage{-2} \section{Una funci�n ``encuentra''} \label{encuentra} \index{recorrido} \index{recorrido eureka} \index{patr�n} \index{patr�n computacional} �Qu� hace la siguiente funci�n? \beforeverb \begin{verbatim} def encuentra(cad, c): indice = 0 while indice < len(cad): if cad[indice] == c: return indice indice = indice + 1 return -1 \end{verbatim} \afterverb % En cierto sentido, \verb|encuentra| es lo contrario del operador \verb|[]|. En lugar de tomar un �ndice y extraer el car�cter correspondiente, toma un car�cter y encuentra el �ndice donde aparece el car�cter. Si el car�cter no se encuentra, la funci�n devuelve {\tt -1}. Este es el primer ejemplo que hemos visto de una sentencia \verb|return| dentro de un bucle. Si \verb|cad[indice] == c|, la funci�n vuelve inmediatamente, escapando del bucle prematuramente. Si el car�cter no aparece en la cadena, el programa sale del bucle normalmente y devuelve \verb|-1|. Este patr�n de computaci�n se llama a veces un recorrido ``eureka'' porque en cuanto encontramos lo que buscamos, podemos gritar ``�Eureka!'' y dejar de buscar. \begin{quote} {\em A modo de ejercicio, modifique la funci�n \verb|encuentra| para que acepte un tercer par�metro, el �ndice de la cadena donde deber�a empezar a buscar.} \end{quote} \section{Bucles y conteo} \label{contador} \index{contador} \index{patr�n} El programa que sigue cuenta el n�mero de veces que la letra \verb|a| aparece en una cadena: \beforeverb \begin{verbatim} fruta = "banana" cuenta = 0 for car in fruta: if car == 'a': cuenta = cuenta + 1 print cuenta \end{verbatim} \afterverb % Este programa muestra otro patr�n de computaci�n llamado {\bf contador}. La variable \verb|cuenta| se incializa a 0 y luego se incrementa cada vez que se encuentra una \verb|a|. ({\bf Incrementar} es aumentar en uno; es lo contario de {\bf decrementar}, y sin relaci�n alguna con ``excremento'', que es un nombre.) Al salir del bucle, \verb|cuenta| contiene el resultado -- el n�mero total de \verb|a|es. \begin{quote} {\em Como ejercicio, encapsule este c�digo en una funci�n llamada {\tt cuentaLetras}, y general�cela de forma que acepte la cadena y la letra como par�metros.} \end{quote} \begin{quote} {\em Como un segundo ejercicio, reescriba esta funci�n para que en lugar de recorrer la cadena, use la versi�n de tres par�metros de {\tt encuentra del anterior}.} \end{quote} \section{El m�dulo ``string''} \index{m�dulo} \index{m�dulo string} El m�dulo \verb|string| contiene funciones �tiles para manipular cadenas. Como es habitual, tenemos que importar el m�dulo antes de poder usarlo: \beforeverb \begin{verbatim} >>> import string \end{verbatim} \afterverb % El m�dulo \verb|string| incluye una funci�n llamada \verb|find| que hace lo mismo que la funci�n \verb|encuentra| que escribimos. Para llamarla debemos especificar el nombre del m�dulo y el nombre de la funci�n por medio de la notaci�n de punto. \beforeverb \begin{verbatim} >>> fruta = "banana" >>> indice = string.find(fruta, "a") >>> print indice 1 \end{verbatim} \afterverb % Este ejemplo demuestra uno de los beneficios de los m�dulos: ayudan a evitar las colisiones entre los nombres de las funciones predefinidas y las definidas por el usuario. Al usar la notaci�n de punto podr�amos especificar qu� versi�n de \verb|find| queremos en caso de haberle daddo un nombre en ingl�s a nuestra funci�n. En realidad, \verb|string.find| es m�s general que nuestra versi�n. Para empezar, puede encontrar subcadenas, no s�lo caracteres: \beforeverb \begin{verbatim} >>> string.find("banana", "na") 2 \end{verbatim} \afterverb % Adem�s, acepta un argumento adicional que especifica el �ndice en el que deber�a comenzar: \beforeverb \begin{verbatim} >>> string.find("banana", "na", 3) 4 \end{verbatim} \afterverb % O puede tomar dos argumentos adicionales que especifican un intervalo de �ndices: \beforeverb \begin{verbatim} >>> string.find("sus", "s", 1, 2) -1 \end{verbatim} \afterverb % En este ejemplo, la b�squeda falla porque la letra {\em s} no aparece en el intervalo de �ndices desde \verb|1| hasta \verb|2| (sin incluir {\tt 2}). \section{Clasificaci�n de caracteres} \label{in} \index{clasificaci�n de caracteres} \index{clasificaci�n!car�cter} \index{uppercase} \index{lowercase} \index{whitespace} 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 m�dulo \verb|string| proporciona varias constantes que son �tiles para estos menesteres. La cadena \verb|string.lowercase| contiene todas las letras que el sistema considera como min�sculas. De forma similar, \verb|string.uppercase| contiene todas las may�sculas. Pruebe lo que sigue y vea qu� obtiene: \beforeverb \begin{verbatim} >>> print string.lowercase >>> print string.uppercase >>> print string.digits \end{verbatim} \afterverb % Podemos usar estas constantes y \verb|find| para clasificar caracteres. Por ejemplo, si \verb|find(lowercase, c)| devuelve un valor que no sea {\tt -1}, entonces \verb|c| es una min�scula: \beforeverb \begin{verbatim} def esMinuscula(c): return find(string.lowercase, c) != -1 \end{verbatim} \afterverb % Alternativamente, podemos aprovecharnos del operador \verb|in|, que determina si un car�cter aparece en una cadena: \beforeverb \begin{verbatim} def esMinuscula(c): return c in string.lowercase \end{verbatim} \afterverb % Como una alternativa m�s, podemos usar el operador de comparaci�n, aunque esta soluci�n s�lo sea pr�ctica para el alfabeto ingl�s: \beforeverb \begin{verbatim} def esMinuscula(c): return 'a' <= c <= 'z' \end{verbatim} \afterverb % Si \verb|c| est� entre {\em a} y {\em z}, tiene que ser una min�scula. \begin{quote} {\em Como ejercicio, explique qu� versi�n de \verb|esMinuscula| cree que es m�s r�pida. �Puede pensar en otras razones aparte de la velocidad para preferir una sobre la otra?} \end{quote} Otra constante definida en el m�dulo \verb|string| puede sorprenderle cuando la imprima: \beforeverb \begin{verbatim} >>> print string.whitespace \end{verbatim} \afterverb % Los caracteres de {\bf whitespace} mueven el cursor sin imprimir nada. Crean los espacios en blanco entre los caracteres visibles (al menos sobre papel blanco). La constante \verb|string.whitespace| contiene todos los caracteres de espacio en blanco, inclu�dos espacio, tabulador (\verb+\t+), y salto de l�nea (\verb+\n+). \index{m�dulo string} \index{m�dulo!string} Hay otras funciones �tiles en el m�dulo \verb|string|, pero este libro no pretende ser un manual de referencia. Por otra parte, la {\em Referencia de la Biblioteca de Python} s� lo es. Junto con un mont�n m�s de documentaci�n, est� disponible en el sitio web de Python, {\tt www.python.org}. \index{{\em Referencia de la Biblioteca de Python}} \section{Glosario} \begin{description} \item[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. \item[recorrer:] Realizar de forma iterativa una operaci�n similar sobre cada uno de los elementos de un conjunto. \item[�ndice:] Una variable o valor usado para seleccionar un miembro de un conjunto ordenado, como puede ser un car�cter de una cadena. \item[porci�n:] Una parte de una cadena especificada por un intervalo de �ndices. \item[mutable:] Un tipo de datos compuesto a cuyos elementos se les puede asignar nuevos valores. \item[contador:] Una variable usada para contar algo, normalmente inicializado a cero e incrementado posteriormente. \item[incrementar:] Aumentar el valor de una variable en una unidad. \item[decrementar:] Disminuir el valor de una variable en una unidad. \item[espacio en blanco:] Cualquiera de los caracteres que mueven el cursor sin imprimir caracteres visibles. La constante \verb|string.whitespace| contiene todos los caracterse de espacio en blanco. \index{tipo compuesto de datos} \index{recorrer} \index{�ndice} \index{porci�n} \index{mutable} \index{contador} \index{incrementar} \index{decrementar} \index{espacio en blanco} \end{description}


Next Up Previous Hi Index

" + str + "

Close window

Hosted by www.Geocities.ws

"); } //-->
Hosted by www.Geocities.ws

1