1.8. Comencemos con los datos¶
Hemos dicho anteriormente que Python soporta el paradigma de programación orientado a objetos. Esto significa que Python considera que los datos son el punto focal del proceso de solución de problemas. En Python, así como en cualquier otro lenguaje de programación orientado a objetos, definimos una clase como una descripción de cómo lucen los datos (el estado) y lo que los datos pueden hacer (el comportamiento). Las clases son análogas a los tipos abstractos de datos porque un usuario de una clase sólo ve el estado y el comportamiento de un ítem de datos. Los ítems de datos se llaman objetos en el paradigma orientado a objetos. Un objeto es una instancia de una clase.
1.8.1. Tipos de datos atómicos incorporados¶
Comenzaremos nuestro repaso considerando los tipos de datos atómicos. Python tiene dos clases numéricas incorporadas principales que implementan los tipos de datos enteros y de punto flotante. Estas clases de Python se llaman int
y float
. Las operaciones aritméticas estándar, +, -, *, /, y ** (potenciación), pueden utilizarse con paréntesis para forzar que el orden de las operaciones se aleje de la precedencia normal del operador. Otras operaciones muy útiles son el operador de residuo (módulo), %, y la división entera, //. Tenga en cuenta que cuando se dividen dos enteros, el resultado es de punto flotante. El operador de división entera devuelve la porción entera del cociente truncando cualquier parte fraccionaria.
El tipo de datos booleano, implementado como la clase bool
de Python, será muy útil para representar valores de verdad. Los posibles valores de estado para un objeto booleano son True
y False
con los operadores booleanos estándar, and
, or
y not
.
>>> True
True
>>> False
False
>>> False or True
True
>>> not (False or True)
False
>>> True and True
True
Los objetos de datos booleanos también se utilizan como resultados para operadores de comparación tales como igualdad (==) y mayor que (\(>\)). Además, los operadores relacionales y los operadores lógicos pueden combinarse para formar preguntas lógicas complejas. La Tabla 1 muestra los operadores relacionales y lógicos con ejemplos mostrados en la sesión que sigue a continuación.
Nombre de la operación |
Operador |
Explicación |
---|---|---|
menor que |
\(<\) |
Operador menor que |
mayor que |
\(>\) |
Operador mayor que |
menor que o igual |
\(<=\) |
Operador menor que o igual a |
mayor que o igual |
\(>=\) |
Operador mayor que o igual a |
igual |
\(==\) |
Operador de igualdad |
no igual |
\(!=\) |
Operador de no igualdad |
and lógica |
\(and\) |
Ambos operandos deben ser True para que el resultado sea True |
or lógica |
\(or\) |
Al menos un operando debe ser True para que el resultado sea True |
not lógica |
\(not\) |
Niega el valor de verdad. si es False lo vuelve True, si es True lo vuelve False |
Los identificadores se utilizan en los lenguajes de programación como nombres. En Python, los identificadores comienzan con una letra o un guión bajo (_), son sensibles a mayúsculas y minúsculas, y pueden ser de cualquier longitud. Recuerde que siempre es una buena idea usar nombres que tengan significado para que su código de programa sea más fácil de leer y entender.
Una variable en Python se crea cuando se utiliza un nombre por primera vez en el lado izquierdo de una instrucción de asignación. Las instrucciones de asignación proporcionan una forma de asociar un nombre a un valor. La variable contendrá una referencia a una pieza de datos y no a los datos en sí. Considere la siguiente sesión:
>>> laSuma = 0
>>> laSuma
0
>>> laSuma = laSuma + 1
>>> laSuma
1
>>> laSuma = True
>>> laSuma
True
La instrucción de asignación laSuma = 0
crea una variable llamada laSuma
y le permite contener la referencia al objeto de datos 0
(ver la Figura 3). En general, se evalúa el lado derecho de la instrucción de asignación y se asigna una referencia al objeto de datos resultante al nombre en el lado izquierdo. En este punto de nuestro ejemplo, el tipo de la variable es entero, ya que es el tipo de los datos a los que se refiere actualmente laSuma
. Si el tipo de datos cambia (véase la Figura 4), como se muestra arriba con el valor booleano True
, también cambia el tipo de la variable (laSuma
es ahora de tipo booleano). La instrucción de asignación cambia la referencia que está siendo retenida por la variable. Ésta es una característica dinámica de Python. La misma variable puede referirse a muchos tipos diferentes de datos.
1.8.2. Tipos de datos de colecciones incorporados¶
Además de las clases numéricas y booleanas, Python tiene una serie de clases de colecciones muy potentes. Las listas, las cadenas y las tuplas son colecciones ordenadas muy similares en la estructura general pero que tienen diferencias específicas que deben ser entendidas para que sean usadas correctamente. Los conjuntos y los diccionarios son colecciones no ordenadas.
Una lista es una colección ordenada de cero o más referencias a objetos de datos de Python. Las listas se escriben como valores delimitados por comas encerrados entre corchetes. La lista vacía es simplemente [ ]
. Las listas son heterogéneas, lo que significa que los objetos de datos no necesitan ser todos de la misma clase y la colección se puede asignar a una variable como se muestra a continuación. El siguiente fragmento muestra una variedad de objetos de datos de Python en una lista.
>>> [1,3,True,6.5]
[1, 3, True, 6.5]
>>> miLista = [1,3,True,6.5]
>>> miLista
[1, 3, True, 6.5]
Tenga en cuenta que cuando Python evalúa una lista, la misma lista es devuelta. Sin embargo, con el fin de recordar la lista para un procesamiento posterior, su referencia debe asignarse a una variable.
Dado que las listas se consideran ordenadas secuencialmente, admiten varias operaciones que se pueden aplicar a cualquier secuencia de Python. La Tabla 2 compendia estas operaciones y la sesión subsiguiente da ejemplos de su uso.
Nombre de la operación |
Operador |
Explicación |
---|---|---|
indización |
[ ] |
Acceso a un elemento de la secuencia |
concatenación |
+ |
Combina secuencias |
repetición |
* |
Concatena un número repetido de veces |
membresía |
in |
Pregunta si un ítem está en una secuencia |
longitud |
len |
Pregunta el número de ítems en la secuencia |
partición |
[ : ] |
Extrae una parte de una secuencia |
Note que los índices para las listas (secuencias) comienzan contando en 0. La operación de partición, miLista[1:3], devuelve una lista de ítems que empieza con el ítem indizado por 1 y que va hasta el ítem indizado por 3 pero sin incluirlo.
A veces, usted querrá inicializar una lista. Esto se puede lograr rápidamente usando la repetición. Por ejemplo,
>>> miLista = [0] * 6
>>> miLista
[0, 0, 0, 0, 0, 0]
Un aspecto muy importante relacionado con el operador de repetición es que el resultado es una repetición de referencias a los objetos de datos en la secuencia. Esto puede verse mejor considerando la siguiente sesión:
La variable A
contiene una colección de tres referencias a la lista original llamada miLista
. Tenga en cuenta que un cambio a un elemento de miLista
se refleja en las tres apariciones en A
.
Las listas admiten varios métodos que se utilizarán para crear estructuras de datos. La Tabla 3 proporciona un resumen. Después se muestran ejemplos de su uso.
Nombre del método |
Uso |
Explicación |
---|---|---|
|
|
Agrega un nuevo ítem al final de una lista |
|
|
Inserta un ítem en la i-ésima posición en una lista |
|
|
Elimina y devuelve el último ítem de una lista |
|
|
Elimina y devuelve el i-ésimo ítem en una lista |
|
|
Modifica una lista para que quede ordenada |
|
|
Modifica una lista para que quede en orden inverso |
|
|
Borra el ítem en la i-ésima posición |
|
|
Devuelve el índice de la primera aparición de |
|
|
Devuelve el número de apariciones de |
|
|
Elimina la primera aparición de |
Usted puede ver que algunos de los métodos, como pop
, devuelven un valor y también modifican la lista. Otros, como reverse
, simplemente modifican la lista sin devolver valor. pop
actuará por defecto sobre el final de la lista, pero también puede eliminar y devolver un ítem específico. El rango de índices que comienza a partir de 0 se utiliza de nuevo para estos métodos. Usted también debe fijarse en la notación familiar de “punto” para pedir a un objeto que invoque un método. miLista.append (False)
se puede leer como “pedir al objeto miLista
que ejecute su método append
y le envíe el valor False
”. Incluso objetos de datos simples tales como los enteros pueden invocar métodos de esta manera.
>>> (54).__add__(21)
75
>>>
En este fragmento pedimos al objeto entero 54
que ejecute su método add
(llamado __add__
en Python) y le pasemos 21
como el valor a sumar. El resultado es la suma, 75
. Por supuesto, solemos escribir esto como 54 + 21
. Diremos mucho más sobre estos métodos más adelante en esta sección.
Una función común de Python que se discute a menudo junto con las listas es la función range
. range
produce un objeto range que representa una secuencia de valores. Mediante el uso de la función list
, es posible ver el valor del objeto range como una lista. Esto se ilustra a continuación.
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(5,10)
range(5, 10)
>>> list(range(5,10))
[5, 6, 7, 8, 9]
>>> list(range(5,10,2))
[5, 7, 9]
>>> list(range(10,1,-1))
[10, 9, 8, 7, 6, 5, 4, 3, 2]
>>>
El objeto range representa una secuencia de enteros. Por defecto, iniciará con 0. Si se proporcionan más parámetros, iniciará y finalizará en determinados puntos e incluso puede omitir ítems. En nuestro primer ejemplo, range(10)
, la secuencia comienza con 0 y va hasta pero no incluye a 10. En nuestro segundo ejemplo, range(5,10)
comienza en 5 y va hasta pero no incluye a 10. range (5,10,2)
se comporta de manera similar, pero omite valores de dos en dos (nuevamente, 10 no está incluido).
Las cadenas son colecciones secuenciales de cero o más letras, números y otros símbolos. Llamamos a estas letras, números y otros símbolos caracteres. Los valores de las cadenas literales se diferencian de los identificadores mediante el uso de comillas (simples o dobles).
>>> "David"
'David'
>>> miNombre = "David"
>>> miNombre[3]
'i'
>>> miNombre*2
'DavidDavid'
>>> len(miNombre)
5
>>>
Dado que las cadenas son secuencias, todas las operaciones para secuencias descritas anteriormente funcionan como se esperaría. Además, las cadenas tienen una serie de métodos, algunos de los cuales se muestran en la Tabla 4. Por ejemplo,
>>> miNombre
'David'
>>> miNombre.upper()
'DAVID'
>>> miNombre.center(10)
' David '
>>> miNombre.find('v')
2
>>> miNombre.split('v')
['Da', 'id']
De estos métodos, split
será muy útil para el procesamiento de datos. split
tomará una cadena y devolverá una lista de cadenas usando el caracter especificado en el argumento como punto de división. En el ejemplo, v
es el punto de división. Si no se especifica ninguna división, el método split busca caracteres de espacios en blanco como tabulación, nueva línea y espacio.
Nombre del método |
Uso |
Explicación |
---|---|---|
|
|
Devuelve una cadena centrada en un campo de tamaño |
|
|
Devuelve el número de apariciones de |
|
|
Devuelve una cadena justificada a la izquierda en un campo de tamaño |
|
|
Devuelve una cadena en minúsculas |
|
|
Devuelve una cadena justificada a la derecha en un campo de tamaño |
|
|
Devuelve el índice de la primera aparición de |
|
|
Divide una cadena en subcadenas en |
Una diferencia importante entre las listas y las cadenas es que las listas se pueden modificar mientras que las secuencias no pueden ser modificadas. Esto se conoce como mutabilidad. Las listas son mutables; Las cadenas son inmutables. Por ejemplo, usted puede cambiar un ítem de una lista mediante la indización y la asignación. Con una cadena tal cambio no está permitido.
>>> miLista
[1, 3, True, 6.5]
>>> miLista[0]=2**10
>>> miLista
[1024, 3, True, 6.5]
>>>
>>> miNombre
'David'
>>> miNombre[0]='X'
Traceback (most recent call last):
File "<pyshell#84>", line 1, in -toplevel-
miNombre[0]='X'
TypeError: object doesn't support item assignment
>>>
Las tuplas son muy similares a las listas en que son secuencias heterogéneas de datos. La diferencia es que una tupla es inmutable, como una cadena. No se puede cambiar una tupla. Las tuplas se escriben como valores delimitados por comas encerrados entre paréntesis. Como secuencias, pueden utilizar cualquier operación descrita anteriormente. Por ejemplo,
>>> miTupla = (2,True,4.96)
>>> miTupla
(2, True, 4.96)
>>> len(miTupla)
3
>>> miTupla[0]
2
>>> miTupla * 3
(2, True, 4.96, 2, True, 4.96, 2, True, 4.96)
>>> miTupla[0:2]
(2, True)
>>>
Sin embargo, si usted intenta cambiar un ítem en una tupla, obtendrá un error. Note que el mensaje de error proporciona la ubicación y el motivo del problema.
>>> miTupla[1]=False
Traceback (most recent call last):
File "<pyshell#137>", line 1, in -toplevel-
miTupla[1]=False
TypeError: object doesn't support item assignment
>>>
Un conjunto es una colección no ordenada de cero o más objetos de datos de Python inmutables. Los conjuntos no permiten duplicaciones y se escriben como valores delimitados por comas encerrados entre llaves. El conjunto vacío está representado por set()
. Los conjuntos son heterogéneos y la colección se puede asignar a una variable como se muestra a continuación.
>>> {3,6,"gato",4.5,False}
{False, 4.5, 3, 6, 'gato'}
>>> miConjunto = {3,6,"gato",4.5,False}
>>> miConjunto
{False, 4.5, 3, 6, 'gato'}
>>>
Aunque los conjuntos no se consideran secuenciales, sí soportan algunas de las operaciones conocidas qe fueron presentadas anteriormente. La Tabla 5 compendia estas operaciones y la siguiente sesión da ejemplos de su uso.
Nombre de la operación |
Operador |
Explicación |
---|---|---|
membresía |
in |
Membresía del conjunto |
longitud |
len |
Devuelve la cardinalidad del conjunto |
|
|
Devuelve un nuevo conjunto con todos los elementos de ambos conjuntos |
|
|
Devuelve un nuevo conjunto con sólo los elementos comunes a ambos conjuntos |
|
|
Devuelve un nuevo conjunto con todos los ítems del primer conjunto que no están en el segundo |
|
|
Pregunta si todos los elementos del primer conjunto están en el segundo |
>>> miConjunto
{False, 4.5, 3, 6, 'gato'}
>>> len(miConjunto)
5
>>> False in miConjunto
True
>>> "perro" in miConjunto
False
>>>
Los conjuntos soportan una serie de métodos que deben ser familiares para aquellos que han trabajado con ellos en el contexto de las matemáticas. La Tabla 6 proporciona un resumen de ellos. Siguen ejemplos de su uso. Tenga en cuenta que union
, intersection
, issubset
y difference
tienen operadores que también se pueden utilizar.
Nombre del método |
Uso |
Explicación |
---|---|---|
|
|
Devuelve un nuevo conjunto con todos los elementos de ambos conjuntos |
|
|
Devuelve un nuevo conjunto con sólo los elementos comunes a ambos conjuntos |
|
|
Devuelve un nuevo conjunto con todos los elementos del primer conjunto que no están en el segundo |
|
|
Pregunta si todos los elementos de un conjunto están en el otro |
|
|
Añade |
|
|
Elimina |
|
|
Elimina un elemento arbitrario del conjunto |
|
|
Elimina todos los elementos del conjunto |
>>> miConjunto
{False, 4.5, 3, 6, 'gato'}
>>> tuConjunto = {99,3,100}
>>> miConjunto.union(tuConjunto)
{False, 4.5, 3, 100, 6, 'gato', 99}
>>> miConjunto | tuConjunto
{False, 4.5, 3, 100, 6, 'gato', 99}
>>> miConjunto.intersection(tuConjunto)
{3}
>>> miConjunto & tuConjunto
{3}
>>> miConjunto.difference(tuConjunto)
{False, 4.5, 6, 'gato'}
>>> miConjunto - tuConjunto
{False, 4.5, 6, 'gato'}
>>> {3,100}.issubset(tuConjunto)
True
>>> {3,100}<=tuConjunto
True
>>> miConjunto.add("casa")
>>> miConjunto
{False, 4.5, 3, 6, 'casa', 'gato'}
>>> miConjunto.remove(4.5)
>>> miConjunto
{False, 3, 6, 'casa', 'gato'}
>>> miConjunto.pop()
False
>>> miConjunto
{3, 6, 'casa', 'gato'}
>>> miConjunto.clear()
>>> miConjunto
set()
>>>
Nuestra colección final de Python es una estructura no ordenada llamada diccionario. Los diccionarios son colecciones de parejas de ítems asociadas en las que cada pareja consiste en una clave y un valor. Esta pareja clave-valor suele escribirse como clave:valor. Los diccionarios se escriben como parejas clave:valor delimitadas por comas encerradas entre llaves. Por ejemplo,
>>> capitales = {'Iowa':'DesMoines','Wisconsin':'Madison'}
>>> capitales
{'Wisconsin': 'Madison', 'Iowa': 'DesMoines'}
>>>
Podemos manipular un diccionario accediendo a un valor a través de su clave o añadiendo otra pareja clave-valor. La sintaxis para el acceso se parece mucho a un acceso de secuencia, excepto que en lugar de utilizar el índice del ítem utilizamos la clave. Agregar un valor nuevo es similar.
Es importante tener en cuenta que el diccionario se mantiene sin un orden particular con respecto a las claves. La primera pareja añadida ('Utah':
'SaltLakeCity'
) fue ubicada como primera en el diccionario y la segunda pareja añadida ('California':
'Sacramento'
) fue ubicada en último lugar. La ubicación de una clave depende de la idea de “transformación de claves” (hashing por su nombre en inglés), que se explicará con más detalle en el Capítulo 4. También mostramos la función len
que desempeña el mismo papel que con las colecciones anteriores.
Los diccionarios tienen métodos y operadores. La Tabla 7 y la Tabla 8 los describen, y la sesión los muestra en acción. Los métodos keys
, values
e items
devuelven objetos que contienen los valores de interés. Se puede usar la función list
para convertirlos en listas. Usted también verá que hay dos variaciones en el método get
. Si la clave no está presente en el diccionario, get
devolverá None
. Sin embargo, un segundo parámetro opcional puede especificar un valor devuelto.
Operador |
Uso |
Explicación |
---|---|---|
|
|
Devuelve el valor asociado con |
|
|
Devuelve |
|
|
Elimina la entrada del diccionario |
>>> extenTel={'david':1410,'brad':1137}
>>> extenTel
{'brad': 1137, 'david': 1410}
>>> extenTel.keys()
dict_keys(['brad', 'david'])
>>> list(extenTel.keys())
['brad', 'david']
>>> extenTel.values()
dict_values([1137, 1410])
>>> list(extenTel.values())
[1137, 1410]
>>> extenTel.items()
dict_items([('brad', 1137), ('david', 1410)])
>>> list(extenTel.items())
[('brad', 1137), ('david', 1410)]
>>> extenTel.get("kent")
>>> extenTel.get("kent","NO HAY ENTRADA")
'NO HAY ENTRADA'
>>>
Nombre del método |
Uso |
Explicación |
---|---|---|
|
|
Devuelve las claves del diccionario en un objeto dict_keys |
|
|
Devuelve los valores del diccionario en un objeto dict_values |
|
|
Devuelve las parejas clave-valor en un objeto dict_items |
|
|
Devuelve el valor asociado con |
|
|
Devuelve el valor asociado con |
Note
Este espacio de trabajo se proporciona para su comodidad. Usted puede usar esta ventana de activecode para probar lo que quiera.