Datos

../../../_images/alexander-sinn-KgLtFCgfC28-unsplash.jpg

Los programas están formados por código y datos. Pero a nivel interno de la memoria del ordenador no son más que una secuencia de bits. La interpretación de estos bits depende del lenguaje de programación, que almacena en la memoria no sólo el puro dato sino distintos metadatos. 1

Cada «trozo» de memoria contiene realmente un objeto, de ahí que se diga que en Python todo son objetos. Y cada objeto tiene, al menos, los siguientes campos:

  • Un tipo del dato almacenado.

  • Un identificador único para distinguirlo de otros objetos.

  • Un valor consistente con su tipo.

../../../_images/object.jpg

Esquema (metadatos) de un objeto en Python

Tipos de datos

A continuación se muestran los distintos tipos de datos que podemos encontrar en Python, sin incluir aquellos que proveen paquetes externos:

Tipos de datos en Python

Nombre

Tipo

Ejemplos

Booleano

bool

True, False

Entero

int

21, 34500, 34_500

Flotante

float

3.14, 1.5e3

Complejo

complex

2j, 3 + 5j

Cadena

str

'tfn', '''tenerife - islas canarias'''

Tupla

tuple

(1, 3, 5)

Lista

list

['Chrome', 'Firefox']

Conjunto

set

set([2, 4, 6])

Diccionario

dict

{'Chrome': 'v79' , 'Firefox': 'v71'}

Variables

Las variables son fundamentales ya que permiten definir nombres para los valores que tenemos en memoria y que vamos a usar en nuestro programa.

../../../_images/name-variable.jpg

Uso de un nombre de variable

Reglas para nombrar variables

En Python existen una serie de reglas para los nombres de variables:

  1. Sólo pueden contener los siguientes caracteres 2:
    • Letras minúsculas.

    • Letras mayúsculas.

    • Dígitos.

    • Guiones bajos (_).

  2. Deben empezar con una letra o un guión bajo, nunca con un dígito.

  3. No pueden ser una palabra reservada del lenguaje («keywords»).

Podemos obtener un listado de las palabras reservadas del lenguaje de la siguiente forma:

>>> help('keywords')

Here is a list of the Python keywords.  Enter any keyword to get more help.

False               class               from                or
None                continue            global              pass
True                def                 if                  raise
and                 del                 import              return
as                  elif                in                  try
assert              else                is                  while
async               except              lambda              with
await               finally             nonlocal            yield
break               for                 not

Nota

Por lo general se prefiere dar nombres en inglés a las variables que utilicemos, ya que así hacemos nuestro código más «internacional» y con la posibilidad de que otras personas puedan leerlo, entenderlo y – llegado el caso – modificarlo. Es sólo una recomendación, nada impide que se haga en castellano.

Importante

Los nombres de variables son «case-sensitive» 3. Por ejemplo, stuff y Stuff son nombres diferentes.

Ejemplos de nombres de variables

Veamos a continuación una tabla con nombres de variables:

Ejemplos de nombres de variables

Válido

Inválido

Razón

a

3

Empieza por un dígito

a3

3a

Empieza por un dígito

a_b_c___95

another-name

Contiene un caracter no permitido

_abc

with

Es una palabra reservada del lenguaje

_3a

3_a

Empieza por un dígito

Convenciones para nombres

Mientras se sigan las reglas que hemos visto para nombrar variables no hay problema en la forma en la que se escriban, pero sí existe una convención para la nomenclatura de las variables. Se utiliza el llamado snake_case en el que utilizamos caracteres en minúsculas (incluyendo dígitos si procede) junto con guiones bajos – cuando sean necesarios para su legibilidad –. 4 Por ejemplo, para nombrar una variable que almacene el número de canciones en nuestro ordenador, podríamos usar num_songs.

Esta convención, y muchas otras, están definidas en un documento denominado PEP 8. Se trata de una guía de estilo para escribir código en Python. Los PEPs 5 son las propuestas que se hacen para la mejora del lenguaje.

Constantes

Un caso especial y que vale la pena destacar son las constantes. Podríamos decir que es un tipo de variable pero que su valor no cambia a lo largo de nuestro programa. Por ejemplo la velocidad de la luz. Sabemos que su valor es constante de 300.000 km/s. En el caso de las constantes utilizamos mayúsculas (incluyendo guiones bajos si es necesario) para nombrarlas. Para la velocidad de la luz nuestra constante se podría llamar: LIGHT_SPEED.

Elegir buenos nombres

Se suele decir que una persona programadora (con cierta experiencia), a lo que dedica más tiempo, es a buscar un buen nombre para sus variables. Quizás pueda resultar algo excesivo pero da una idea de lo importante que es esta tarea. Es fundamental que los nombres de variables sean autoexplicativos, pero siempre llegando a un compromiso entre ser concisos y claros.

Supongamos que queremos buscar un nombre de variable para almacenar el número de elementos que se deben manejar en un pedido:

  1. n

  2. num_elements

  3. number_of_elements

  4. number_of_elements_to_be_handled

No existe una regla mágica que nos diga cuál es el nombre perfecto, pero podemos aplicar el sentido común y, a través de la experiencia, ir detectando aquellos nombres que sean más adecuados. En el ejemplo anterior, quizás podríamos descartar de principio la opción 1 y la 4 (por ser demasiado cortas o demasiado largas); nos quedaríamos con las otras dos. Si nos fijamos bien, casi no hay mucha información adicional de la opción 3 con respecto a la 2. Así que podríamos concluir que la opción 2 es válida para nuestras necesidades. En cualquier caso esto dependerá siempre del contexto del problema que estemos tratando.

Asignación

En Python se usa el símbolo = para asignar un valor a una variable:

../../../_images/assignment.jpg

Asignación de valor a nombre de variable

Nota

Hay que diferenciar la asignación en Python con la igualación en matemáticas. El símbolo = lo hemos aprendido desde siempre como una equivalencia entre dos expresiones algebraicas, sin embargo en Python nos indica una sentencia de asignación, del valor (en la derecha) al nombre (en la izquierda).

Algunos ejemplos de asignaciones a variables:

>>> total_population = 157503
>>> avg_temperature = 16.8
>>> city_name = 'San Cristóbal de La Laguna'

Algunos ejemplos de asignaciones a constantes:

>>> SOUND_SPEED = 343.2
>>> WATER_DENSITY = 997
>>> EARTH_NAME = 'La Tierra'

Python nos ofrece la posibilidad de hacer una asignación múltiple de la siguiente manera:

>>> tres = three = drei = 3

En este caso las tres variables utilizadas en el «lado izquierdo» tomarán el valor 3.

Recordemos que los nombres de variables deben seguir unas reglas establecidas, de lo contrario obtendremos un error sintáctico del intérprete de Python:

>>> 7floor = 40  # el nombre empieza por un dígito
  File "<stdin>", line 1
    7floor = 40
         ^
SyntaxError: invalid syntax

>>> for = 'Bucle'  # el nombre usa la palabra reservada "for"
  File "<stdin>", line 1
    for = 'Bucle'
        ^
SyntaxError: invalid syntax

>>> screen-size = 14  # el nombre usa un caracter no válido
  File "<stdin>", line 1
SyntaxError: can't assign to operator

Asignando una variable a otra variable

Las asignaciones que hemos hecho hasta ahora han sido de un valor literal a una variable. Pero nada impide que podamos hacer asignaciones de una variable a otra variable:

>>> people = 157503
>>> total_population = people
>>> total_population
157503

Eso sí, la variable que utilicemos como valor de asignación debe existir previamente, ya que si no es así, obtendremos un error informando de que no está definida:

>>> total_population = lot_of_people
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'lot_of_people' is not defined

De hecho, en el lado derecho de la asignación pueden aparecer expresiones más complejas que se verán en su momento.

Conocer el valor de una variable

Hemos visto previamente cómo asignar un valor a una variable, pero aún no sabemos cómo «comprobar» el valor que tiene dicha variable. Para ello podemos utilizar dos estrategias:

  1. Si estamos en una «shell» de Python, basta con que usemos el nombre de la variable:

    >>> final_stock = 38934
    >>> final_stock
    38934
    
  2. Si estamos escribiendo un programa desde el editor, podemos hacer uso de print:

    final_stock = 38934
    print(final_stock)
    

Nota

print sirve también cuando estamos en una sesión interactiva de Python («shell»)

Conocer el tipo de una variable

Para poder descubrir el tipo de un literal o una variable, Python nos ofrece la función type(). Veamos algunos ejemplos de su uso:

>>> type(9)
int

>>> type(1.2)
float

>>> height = 3718
>>> type(height)
int

>>> sound_speed = 343.2
>>> type(sound_speed)
float

Ejercicio

  1. Asigna un valor entero 2001 a la variable space_odyssey y muestra su valor.

  2. Descubre el tipo del literal 'Good night & Good luck'.

  3. Identifica el tipo del literal True.

  4. Asigna la expresión 10 * 3.0 a la variable result y muestra su tipo.

Solución: numbers.py

Mutabilidad

Nivel avanzado

Las variables son nombres, no lugares. Detrás de esta frase se esconde la reflexión de que cuando asignamos un valor a una variable, lo que realmente está ocurriendo es que se hace apuntar el nombre de la variable a una zona de memoria en el que se representa el objeto (con su valor).

Si realizamos la asignación de una variable a un valor lo que está ocurriendo es que el nombre de la variable es una referencia al valor, no el valor en sí mismo:

>>> a = 5
../../../_images/var-memory1.png

Representación de la asignación de valor a variable

Si ahora «copiamos» el valor de a en otra variable b se podría esperar que hubiera otro espacio en memoria para dicho valor, pero como ya hemos dicho, son referencias a memoria:

>>> b = a
../../../_images/var-memory2.png

Representación de la asignación de una variable a otra variable

La función id() nos permite conocer la dirección de memoria 6 de un objeto en Python. A través de ella podemos comprobar que los dos objetos que hemos creado «apuntan» a la misma zona de memoria:

>>> id(a)
4445989712

>>> id(b)
4445989712

¿Y esto qué tiene que ver con la mutabilidad? Pues se dice, por ejemplo, que un entero es inmutable ya que a la hora de modificar su valor obtenemos una nueva zona de memoria, o lo que es lo mismo, un nuevo objeto:

>>> a = 5
>>> id(a)
4310690224

>>> a = 7
>>> id(a)
4310690288

Sin embargo, si tratamos con listas, podemos ver que la modificación de alguno de sus valores no implica un cambio en la posición de memoria de la variable, por lo que se habla de objetos mutables.

Ejecución paso a paso a través de Python Tutor:

La característica de que los nombres de variables sean referencias a objetos en memoria es la que hace posible diferenciar entre objetos mutables e inmutables:

Inmutable

Mutable

bool

list

int

set

float

dict

str

tuple

Importante

El hecho de que un tipo de datos sea inmutable significa que no podemos modificar su valor «in-situ», pero siempre podremos asignarle un nuevo valor (hacerlo apuntar a otra zona de memoria).

Funciones «built-in»

Nivel intermedio

Hemos ido usando una serie de funciones sin ser especialmente conscientes de ello. Esto se debe a que son funciones «built-in» o incorporadas por defecto en el propio lenguaje Python.

Funciones «built-in»

abs()

delattr()

hash()

memoryview()

set()

all()

dict()

help()

min()

setattr()

any()

any()

hex()

next()

slice()

ascii()

divmod()

id()

object()

sorted()

bin()

enumerate()

input()

oct()

staticmethod()

bool()

eval()

int()

open()

str()

breakpoint()

exec()

isinstance()

ord()

sum()

bytearray()

filter()

issubclass()

pow()

super()

bytes()

float()

iter()

print()

tuple()

callable()

format()

len()

property()

type()

chr()

frozenset()

list()

range()

vars()

classmethod()

getattr()

locals()

repr()

zip()

compile()

globals()

map()

reversed()

__import__()

complex()

hasattr()

max()

round()

Los detalles de estas funciones se puede consultar en la documentación oficial de Python.

AMPLIAR CONOCIMIENTOS

1

Foto original de portada por Alexander Sinn en Unsplash.

2

Para ser exactos, sí se pueden utilizar otros caracteres, e incluso emojis en los nombres de variables, aunque no suele ser una práctica extendida, ya que podría dificultar la legibilidad.

3

Sensible a cambios en mayúsculas y minúsculas.

4

Más información sobre convenciones de nombres en PEP 8.

Del término inglés «Python Enhancement Proposals».

6

Esto es un detalle de implementación de CPython.