Aprende Python desde cero a avanzado curso completo

Firtmiracle el
Aprende Python desde cero a avanzado curso completo

En esta ocasion hablaremos del lenguaje de programacion Python3, realizaremos todo un curso completo desde lo mas basico y explicaremos todo lo escencial para que se pueda llegar a dominar este lenguaje.

El curso se ira actualizando constantemente! - Ultima actualización 14 - 06 - 2023

Que es Python3?

Python3 es un lenguaje de programación ampliamente utilizado en las aplicaciones web, el desarrollo de software, la ciencia de datos y el machine learning. Es preferido entre los desarrolladores porque es eficiente y fácil de aprender, además de que se puede ejecutar en muchas plataformas diferentes, se integra bien a todos los tipos de sistemas y aumenta la velocidad del desarrollo. El software podemos descargarlo gratis de su pagina oficial.

Indice y Estructura

Sintaxis #

Cuando hablamos de la sintaxis en Python3, nos referimos como en todo lenguaje al correcto uso y orden de las palabras que utilizamos para comunicarnos. Por ello, en Python3 también es necesario cumplir ciertos requisitos a la hora de expresarnos.

Comenzaremos con la sintaxis tipica que nos ayuda a imprimir los valores concretamente su nombre es print que viene a ser una funcion interna de Python que recibe una variable o tipo de dato y nos lo muestra por pantalla, por ahora solo hay que tener presente el concepto de print ya que mas adelante profundizaremos en los demas conceptos que nos ayudaran a comprender mejor como funciona este lenguaje.

print("Hola Python3")

Hola Python3

Variables #

Una variable es un elemento de un lenguaje de programación que tiene asignado un valor determinado. Para crear una variable en Python3 debemos proporcionarle un nombre y asignarle un valor utilizando el símbolo =.

variable = "Hola Python3"

print(variable)

Hola Python3

Ahora el valor asignado a la variable puede cambiar a lo largo del codigo a otra difierente.

variable = "Hola Python3"

print(variable)

Hola Python3

variable2 = "Adios Python3"

print(variable)

Adios Python3

Tipos de Variables

Existen 4 tipos de variables principales o primitivas en Python3, concretamente estas son:

Tipoint: Para representar numeros enteros. Tipo string: Para representar texto o cadenas. Tipo boolean: Para representar datos binarios, es decir que pueden tomar los valores True o False. Tipo float: Para representar numeros con decimales.

Representacion Tipo
numeros enteros int
cadenas de texo string
numeros decimales float
dato binario(True o False) boolean

Definimos un conjunto de variables segun su tipo y usamos la funcion reservada de python type() para ver el tipo de variable segun su asignacion:

variable1 = 10

variable4 = 2.4

variable2 = "Hola Python"

variable3 = True

variable4 = 2.4

type(variable1)

int

type(variable2)

str

type(variable3)

bool

type(variable4)

float

Asignación Multiple de Variables

En Python3 podemos asignar una variable a otra variable diferente.

variable = "Hola Python3"

variable2 = variable

print(variable2)

Hola Python3

Sintaxis de Variables

En Python3 se debe cumplir con las reglas sintácticas definidas por el leguaje. A continuación indicamos las reglas que debemos cumplir cuando definimos el nombre de una variable:

  • Las variables en Python3 pueden tener cualquier longitud y pueden consistir en letras mayúsculas y minúsculas A-Z, a-z, dígitos del 0-9 y el carácter de subrayado o subguion _
_variable = "Hola Python3"

print(_variable)

Hola Python3

vAriAbLe = "Hola Python3"

print(vAriAbLe)

Hola Python3

variable_1_1 = "Hola Python3"

print(variable_1_1)

Hola Python3
  • Si no se cumple con las reglas definidas de sintaxys, emitiran un error
  variable$ = "Hola Python3"

    File "<iPython3-input-12-f520f3dd0eb3>", line 1
      variable$ = "Hola Python3"
         ^
  SyntaxError: invalid syntax
  • El nombre de una variable puede contener dígitos, pero el primer caracter de un nombre de variable no puede ser un dígito.
  1variable = "Hola Python3"

    File "<iPython3-input-13-905ee4ad3fed>", line 1
      1variable = "Hola Python3"
     ^
  SyntaxError: invalid syntax
  • El nombre de las variables en Python3 es sensible a mayúsculas y minúsculas
   Variable1 = "Hola Python3"

   print(variable1)

   ---------------------------------------------------------------------------
   NameError                                 Traceback (most recent call last)
   <iPython3-input-15-32693f267891> in <module>
   ----> 1 print(variable1)

   NameError: name 'variable1' is not defined

Strings #

Un string se corresponde con un conjunto de caracteres que forman una cadena de texto.

La sintaxis que debemos utilizar para definir strings en Python consiste en situar los caracteres entre " o '

variable1 = "Esto es mi primer string"

variable2 = 'Esto es mi segunda string'

La flexibilidad de definir string con el caracter “ y el caracter ‘ nos permite definir cadenas de texto que contienen esos mismos caracteres.

variable1 = 'Los tipos strings pueden definirse con el caracter "'

variable2 = "Los tipos strings pueden definirse con el caracter '"

print(variable1)

Los strings pueden definirse con el caracter "

print(variable2)

Los strings pueden definirse con el caracter '

Indexación

En muchos tipos de datos en Python3 se puede acceder a los elementos individuales de un conjunto de datos directamente mediante un índice numérico o un valor clave. Este proceso se denomina indexación.

En Python3, las cadenas son secuencias ordenadas de caracteres, y por lo tanto pueden ser indexadas de esta manera. Se puede acceder a los caracteres individuales de una cadena especificando el nombre de la cadena seguido de un número entre corchetes [].

El primer carácter de la cadena tendra el índice 0, el siguiente el índice 1, y así sucesivamente. El índice del último carácter será la longitud de la cadena menos uno.

lenguaje = "Python"

lenguaje[0]

'P'

lenguaje[2]

't'

Podemos tambien utilizar números negativos para extraer los caracteres por el final de la cadena de texto, donde -1 seria la parte final y asi sucesivamente de derecha a izquierda.

lenguaje[-1]

'n'

lenguaje[-3]

'h'

Slicing

Python3 permite una sintaxis específica de indexación que extrae subcadenas de una cadena de texto, a esto se denomina ‘slicing.

La sintaxis que se utiliza para extraer una subcadena de una cadena de nombre micadena es de la forma micadena[x:y], esto devuelve la parte de la cadena micadena que comienza en la posición x,y termina en la posición y; con la exepción de que no se incluye el último caracter.

lenguaje = "Hola Python"

lenguaje[0:4]

'Hola'

lenguaje[-6:-1]

'Pytho'

Podemos observar que efectivamente no se incluye el ultimo caracter que se especifica: ojo tener en cuenta que los espacios tambien son caracteres correspondientes a una cadena vacia

Pero que pasaria entonces si no indicamos uno de los numeros:

lenguaje = "Hola Python"

lenguaje[-6:]

'Python'

lenguaje[5:]

'Python'

Si no indicamos alguno de los numeros lo que hace Python3 es leer hasta el final.

Stride

Es una variante más del slicing. Si se añade un : adicional y un tercer índice, se designa una stride, que indica cuantos caracteres saltar hasta obtener el siguiente caracter.

Este salto lo hara contando el propio caracter.

lenguaje = "Hola Python"

lenguaje[0:4:2]

'Hl'

lenguaje[0:4:1]

'Hola'

nombre[0:8:3]

'ha'

Modificación de Strings

Una string es un tipo de dato que en Python3 se considera inmutable, esto quiere decir que no podemos modificar una parte de un string asociada a una variable

lenguaje = "Python"

lenguaje[2]

't'

lenguaje[2] = 'a'

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-37-3f77b4874756> in <module>
----> 1 lenguaje[2] = 'a'

TypeError: 'str' object does not support item assignment

Pero a pesar de no poderse modificar el contenido de una string, si se puede asignar un string diferente a la variable.

lenguaje = "golang"

print(lenguaje)

golang

Strings de multiples lineas

Si en alguna ocasion queremos definir strings de varias lineas podemos hacerlo de varias formas en Python3

Una de ellas seria introducir el caracter \n en la posicion de la cadena donde queremos que realize el salto de linea

lenguaje = "Mi\nlenguaje\nfavorito\nes\nPython"

print(lenguaje)
Mi
lenguaje
favorito
es
Python

Otra opción tambien podria usar los caracteres """

lenguaje = """Mi
lenguaje
favorito
es
Python
"""

print(lenguaje)
Mi
lenguaje
favorito
es
Python

Numeros

Existen 3 tipos de datos numéricos: enteros int, números de punto flotante float y números complejos.

Numeros Enteros

Los números enteros son aquellos que no tienen parte decimal. En Python3 se referencian con la palabra int.

num = 10

No olvidemos que es muy importante la diferencia de un número entero y una cadena de texto que representa un número entero.

num = 10
num = "10"

Podemos convertir una cadena de texto que representa un número entero en un valor numérico utilizando la función int()

numero = "10"

print(numero)

'10'

numero2 = int(numero)

print(numero2)

10

Para separar algunos dígitos para que sea más facil de leer. No podemos usar el . o , , para esto Python3 nos da la opcion de usar _:

numero = 5000000

print(numero)

5000000

numero2 = 5_000_000

print(numero2)

5000000

No hay límite en el tamaño de los números enteros que podemos definir, ya que se pueden definir números enteros tan grandes como la memoria de nuestro sistema soporte.

numero = 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

print(numero)

100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Numeros Flotantes

Los números flotantes son aquellos que tienen una parte decimal, en Python3 se referencian con la palabra float.

numero = 10.5

De igual manera que con los números enteros, se puede convertir una cadena de texto que representa un número flotante a un valor numérico utilizando la función float()

numero = "12.4"

print(numero)

'12.4'

numero2 = float(numero)

print(numero2)

12.4

Existen tres formas de representarlos en Python3.

numero1 = 1000.0

numero2 = 1_000.0

numero3 = 1e3

print(numero1)

1000.0

print(numero2)

1000.0

print(numero3)

1000.0

A diferencia que los números enteros, los número de flotantes si tienen un tamaño máximo en Python3. Aunque el tamaño máximo dependera de nuestro sistema, las cifras cercanas o mayores a 2e400 que equivale a (2x10)^400 suelen superar el tamaño máximo.

numero = 2e400

print(numero)

inf

Python3 devuelve inf haciendo referencia a infinito.

Numeros complejos

Hay pocos lenguajes de programacion que ofrecen soporte integrado para números complejos y Python3 es uno de ellos. Aunque los números complejos no suelen aparecer fuera de los dominios de la computación científica, pueden ser de gran utilidad en dominios que usen técnicas estadísticas.

Un número complejo esta formado por 2 componentes distintos: una parte real y una parte imaginaria.

En Python3 podemos definir un numero complejo, se define la parte real seguida de un símbolo + y la parte imaginaria terminando con la letra j.

numero = 2 + 4j

print(numero)

(2+4j)

numero.real

2.0

numero.imag

4.0

Comentarios #

Los comentarios son parte fundamental en cualquier lenguaje de programación. Permiten describir partes del código que desarrollamos de manera que sea mucho más facil de comprender. Poner comentarios en nuestro código es una muy buena práctica que debemos realizar.

La manera más simple de poner comentarios en Python3 es utilizando el símbolo #

# Este es mi comentario

Podemos hacer lo mismo despues de escribir una sentencia en nuestro codigo haciendo referencia al significado de esta:

variable = "Hola Python3" # Esto es una variable

Comentarios de varias lineas

Hay ocasiones en que necesitemos poner comentarios de varias líneas. Python3 no permite crear un comentario de varias líneas utilizando el mismo símbolo #.

# Este comentario
# tiene varias lineas
# para mi ejemplo en Python3

Existe una manera mas sencilla y comoda de hacer comentarios en Python3 con el uso de """ todo el comentario """.

"""
Este comentario
tiene varias líneas
para mi ejemplo en Python3
"""

Operadores Aritmeticos #

A continuación se muestran los operadores aritméticos soportados por Python3:

Operador Significado
a + b suma
a - b resta
a * b multiplicacion
a / b division
a % b modulo
a // b division de enteros
a ** b exponencial

Suma y Resta

Los operadores suma +y resta - se pueden aplicar a distintos tipos de datos.

Sumar y restar datos numericos

Al sumar o restar tipos de datos numericos obtenemos el resultado matematico.

numero1 = 10

numero2 = 8

print(numero1 + numero2)

18

print(numero1 - numero2)

8

print(numero2 - numero1)

-2

numero3 = 2.5

numero4 = 1.5

print(numero3 + numero4)

4.0

print(numero3 - numero4)

1.0

Sumar y restar datos strings

Cuando sumamos tipos de datos strings se concatenan las variables.

texto1 = "Hola"

texto2 = "Python"

print(texto1 + texto2)

'HolaPython'

Si queremos agregar un espacio, debemos agregar una cadena vacia " ", sin embargo no podemos restar dichas cadenas.

print(text1 + " " + text2)

'Hola Python'

print(texto1 - texto2)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-16-ed11b0c86524> in <module>
----> 1 texto1 - texto2

TypeError: unsupported operand type(s) for -: 'str' and 'str'

Multiplicación y División

Los operadores de multiplicacion * y division / son operadores binarios que pueden aplicarse sobre distintos tipos de datos.

multiplicar y dividir datos numericos

numero1 = 20

numero2 = 4

numero1 * numero2

80

# IMPORTANTE: El resultado al dividir siempre es un float

print(numero1 / numero2)

5.0

multiplicar y dividir datos strings

No podemos multiplicar o dividir cadenas de texto.

texto1 = "Hola"

texto2 = "Python"

texto1 * texto2

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-4d766fa04d9a> in <module>
----> 1 texto1 * texto2

TypeError: can't multiply sequence by non-int of type 'str'

print(texto1 / texto2)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-7ba20b66d6c5> in <module>
----> 1 texto1 / texto2

TypeError: unsupported operand type(s) for /: 'str' and 'str'

Pero si podemos multiplicar una cadena de texto por un numero entero, que imprime el numero de veces de la cadena segun el que numero por el que multiplicamos.

texto1 * 3

'HolaHolaHola'

Modulo

El operador modulo % es un operador binario que devuelve el resto de una división entre tipos de datos numericos ya sean enteros o flotantes.

numero1 = 10

numero2 = 7

print(numero1 % numero2)

3

print(numero2 % numero1)

7

numero1 = 10.5

numero2 = 7.2

print(numero1 % numero2)

3.3

Exponencial

El operador exponencial ** es un operador binario que se aplica solo en tipos de datos numéricos.

numero1 = 5

numero1 ** 2

25

numero ** 3

125

texto1 = "Hola Python"

texto1 ** 2

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-33-a3cd4ee7680f> in <module>
----> 1 texto1 ** 2

TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

Division Entera

El operador divison entera //es un operador binario que se aplica sobre tipos de datos numéricos y devuelve la parte entera del resultado.

numero1 = 10

numero2 = 7

print(numero1 / numero2)

1.4285714285714286

print(numero1 // numero2)

1

Operadores de Asignación #

Anteriormente ya hemos usado el operador de asignación = para asignar un valor a una variable.

Sin embargo Python3 nos proporciona un mecanismo para combinar operadores aritméticos y operadores de asignación simplificando nuestro codigo. Esa combinación se denomina Augmented Assignment.

Operador   Significado
a += 4 es igual a a = a + 4
a -= 8 es igual a a = a - 8
a *= 10 es igual a a = a * 10
a /= 5 es igual a a = a / 5

Veamos unos ejemplos:

numero = 15

numero += 5

print(numero)

20

numero2 = 20

numero2 *= 2

print(numero2)

40

numero3 = 8

numero3 -= 3

print(numero3)

5

Booleanos #

Los tipos de datos Boolenos en Python se representan con el tipo bool y reciben únicamente dos posibles valores:

  • True
  • Fase
variable = True

print(variable)

True

Podemos usar la funcion reservada type para ver el tipo de variable

variable = True

type(varaible)

bool

variable2 = False

type(variable2)

bool

Una cosa a tener en cuenta es que las palabras True y False son palabras reservadas dentro de Python3 y no se les puede asignar ningún valor.

True = "Hola Python"

  File "<ipython-input-7-31dbcec71c48>", line 1
    True = "Hola Python"
    ^
SyntaxError: cannot assign to True

Operadores de Comparación #

Son los que evalúan la relación que existe entre dos valores en Python. Existen diferentes tipos:

Operador Ejemplo Significado
== a == b Igual a
!= a != b No igual a
< a < b Menor que
<= a <= b Menor que o igual a
> a > b Mayor que
>= a >= b Mayor que o igual a

Comparación entre datos numericos

A continacion veremos algunos ejemplos

numero1 = 4

numero2 = 8

numero1 == 4

True

numero1 == numero2

False

numero1 == 4.0

True

numero1 != 4

False

numero1 != numero2

True

Otros ejemplos

numero1 = 10

numero2 = 15

numero1 < numero2

True

numero2 < numero1

False

numero1 <= 10.0

True

Comparación entre datos strings

texto1 = "cadena de texto"

texto2 = "cadena de texto 2"

texto1 == "cadena de texto"

True

text1 == text2

False

text1 != text2

True

Ahora veamos un tipo de comparación mas inusual

texto1 = "Cadena de mi texto"

texto2 = "texto"

texto1 < texto2

True

Podemos ver algo muy extraño

Esta comparación utiliza un orden lexicográfico: primero se comparan los dos primeros elementos, y si estos son diferentes, determina el resultado de la comparación; si son iguales, se comparan los dos siguientes elementos, y así sucesivamente, hasta que se agote cualquiera de las dos secuencias.

y ahora se preguntaran si segun el principio tenemos arriba como primer caracter de texto1 -> C y de texto2 -> t como entonces lo esta haciendo?

Pues esto es por la sencilla razon de que esta comparacion lo realiza utilizando los equivalentes numericos de cada caracter, esto mediante la funcion reservada ord()que recibe un caracter y se encarga de transformar un caracter a codigo unicode.

Veamoslo mejor con el ejemplo anterior:

#texto1 = "Cadena de mi texto"
#texto2 = "texto"
#condicion texto1 < texto2

"Cadena de mi texto" < "texto"

True

#Cojemos los primeros caracteres de ambas variables y les aplicamos la funcion ord()

ord('C')

67

ord('t')

116

#tendriamos que C = 67 y t = 116

67 < 116

True

Despues de analizar el ejemplo anterior, efectivamente vemos que la condicion era cierta y ahora nos queda claro como es que funciona.

Operadores de Identidad #

Los operadores de identidad se utilizan para comparar objetos. Sin embargo, no comparan si los objetos son iguales, en su lugar, comparan si son el mismo objeto:

Operador Ejemplo Significado
is x is y Devuelve True si las dos variables son el mismo objeto
is not x is not y Devuelve `True si las dos variables no son el mismo objeto

Veamoslo mejor en un caso practico:

tenemos dos variables:

texto1 = "Hola Python"

text2 = "Hola Python"

Vemos que ambas variables tienen el mismo valor, pero si aplicamos la funcion reservada id() en cada variable nos da un valor diferente.

id(texto1)

140608469061488

id(texto2)

140608469060976

Te preguntaras a que corresponde el valor que nos muestra despues de aplicar la funcion; pues el resultado viene a ser el valor de la porcion de memoria que se le asigna a esa variable en ese preciso momento, ya que si volvemos a crear la misma variable con el mismo valor de nuevo nos mostrara un valor diferente.


texto1 = "Hola Python"

id(texto1)

140608469400944

Ahora aplicaremos la comparacion de indentidad a nuestras dos variables previamente creadas:


texto1 is texto2

False

texto1 == texto2

True

En el resultado podemos apreciar que is nos devuelve False a diferencia de cuando aplicamos == que nos devuelve True:

Esto se debe a que == solo nos compara que las variables contengan el mismo valor, pero el is nos compara que ambas variables sean el mismo objeto creado en la misma porcion de memoria en otras palabras si tienen el mismo identificador que nos mostraba la funcion id().

Como en el caso siguente que crearemos una nueva variable texto3 y la igualaremos a la anterior variable que creamos texto1, en este caso la variable texto3 heredara todo de la variable texto1 esto incluye la porcion de memoria en la que se creo.

Por lo tanto a la hora de ejecutar nuevamente el operador de identidad is esta vez nos dara el valor de True.

texto3 = texto1

texto3 is texto1

True

Operadores de Pertenencia #

Los operadores de pertenencia se utilizan para evaluar sin una secuencia se encuentra presente en un objeto.

Operador Ejemplo Significado
in x in y Devuelve True si la secuencia x se encuntra presente en y, de lo contrario devuelve False
not in x not in y Devuelve True si la secuencia x no se encuentra en y, de lo contrario devuelve False

Veamoslo en un ejemplo:

Obervamos que si la secuencia en este caso cadena esta presente en la variable texto, esto nos responde True ya que solo debe incluirse para que se cumpla esta condicion.

texto = "Mi cadena de texto"

"cadena" in texto

True

"hola" in texto

False

"e" in text

True

Pero si intentamos hacer el mismo proceso en un numero entero, recibimos un error ya que el operador in solo sirve para secuencias que son iterables

num = 1345678

1 in numero
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-882699b1f88c> in <module>
----> 1 1 in numero

TypeError: argument of type 'int' is not iterable

Operadores Logicos #

Los operadores lógicos modifican y unen expresiones evaluadas en contexto booleano para crear condiciones más complejas.

Operador Ejemplo Significado
not not x Devuelve True si x el False, de lo contrario devuelve True
or x or y Devuelve True si x o y son True, de lo contrario devuelve False
and x and y Devuelve True si ambos x como y son True, de lo contrario devuelve False

Operador not

Evaluamos la expresion y con not invierte el valor que nos devuelve una expresion

numero = 10

numero < 20

True

not numero < 20

False

Operador or

Observamos que el resultado nos devuelve True, puesto que si bien la primera condicion es False, con el uso del operador or solo necesita devolver una de ellas True, concretamente ya que la segunda condicion si se cumplia.

numero1 = 10

numero2 = 20

numero1 < 5

False

numero1 < 5 or numero2 > 10

True

Operador and

El operador and si requiere que se cumpla la evaluacion de todas las expresiones para que devuelva un valor True

numero1 = 5

numero2 = 10

numero1 < 8 and numero2 > 15

False

numero1 < 10 and numero2 > 7

True

Listas #

Las listas son un tipo de dato complejo y particular en Python3. Una lista se corresponde con una colección arbitraria de objetos. Las listas son similares a estructuras conocidas como arrays en otros lenguajes de programación pero con la diferencia de que en Python3 aportan mas flexibilidad.

En Python3 se representan con el tipo list y la sintaxis que se utiliza para definirlas consiste en indicar una lista de objetos separados entre comas y encerrados entre corchetes: [objeto1, objeto2, …, objeton]

Veamoslo de manera practica

  • Podemos una lista con datos numericos.
lista = [1, 2, 3, 4, 5]

type(lista)

list

print(lista)

[1, 2, 3, 4, 5]
  • Tambien crear una lista con tipo de datos string
lista2 = ["texto1", "texto2", "texto3"]

type(lista2)

list

print(lista2)

['texto1', 'texto2', 'texto3']

Vemos que tenemos una lista igual a la anterior pero con la diferencia que esta contiene cadenas de texto.

  • El orden en el que se especifican los elementos cuando se define una lista es relevante y se mantiene durante toda su vida.
lista = ['n1', 'n2', 'n3']

print(lista)

['n1', 'n2', 'n3']
  • Podemos comparar las listas con los operadores mencionados anteriormente.
lista1 = ['n1', 'n2', 'n3']

lista2 = ['n2', 'n1', 'n3']

lista1 == lista2

False

'n1' in lista2

True

lista1 in lista2

False

lista1 == ['t1', 't2', 't3']

True

lista1 is lista2

False
  • Las lista pueden contener distintos tipos de datos.
lista = [1, 2, "hola", "python"]

print(lista)

[1, 2, 'hola', 'python']

Una cosa super interesante es que una lista puede contener una función estas las veremos mas adelante pero es importante mantenerlo presente

def funcion():
    print("Hola python")

lista = ["texto1", "texto2", funcion]

print(lista)

['texto1', 'texto2', <function funcion at 0x0000012D476D0EE0>]

Acceso a elementos de una lista

Todas las variaciones vistas en la sección de strings (indexing, slicing, stride) aplican a las listas.

indexing

lista = ["texto1", "texto2", "texto3", "texto4", "texto5"]

lista[0]

'texto1'

lista[-1]

'texto5'

slicing

lista = ["texto1", "texto2", "texto3", "texto4", "texto5"]

lista[2:4]

['texto3', 'texto4']

lista[:3]

['texto1', 'texto2', 'texto3']

lista[2:]

['texto3', 'texto4', 'texto5']

stride

lista = ["texto1", "texto2", "texto3", "texto4", "texto5"]

lista[0:4:2]

['texto1', 'texto3'

otra cosa interesante es que podemos utilizar el concepto de stride para darle la vuelta a una lista

lista

['texto1', 'texto2', 'texto3', 'texto4', 'texto5']

lista[::-1]

['texto5', 'texto4', 'texto3', 'texto2', 'texto1']

Una de las pocas construcciones sintácticas en cuanto a la indexación que cambia entre los strings y las listas es [:].

  • Cuando lo usamos nos devuelve una referencia al propio objeto
texto = "Hola python"

texto[:]

'Hola python'

texto[:] is texto

True
  • Al utilizarlo con una lista nos devuelve una copia del objetivo -> ojo no el mismo.
lista = [1, 2, 3, 4]

lista[:]

[1, 2, 3, 4]

lista[:] is lista

False

Operaciones con listas

Las listas soportan muchos de los operadores y funciones de Python como los que vimos anteriormente.

Al sumar las listas estas se anidan

lista1 = [1, 2, 3]

lista2 = [4, 5, 6]

lista1 + lista2

[1, 2, 3, 4, 5, 6]

Cuando usamos el operador de multiplicación, esto hace que se multipliquen sus mismos valores segun el numero por el cual se le multiplique.

lista1 = [1, 2, 3]

lista1 * 2

[1, 2, 3, 1, 2, 3]

Tambien podemos ver la longitud, el valor minimo y el maximo de una lista

lista1 = [1, 2, 3]

lista2 = [4, 5, 6]

len(lista1)

3

min(lista1)

1

max(lista2)

6

Solo podemos hacer operaciones entre listas, ya que si tratamos de hacer operaciones con otros tipos en este caso un numero int nos arrojara un error.

[1, 2, 3] + 4

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-95-5842ff442cc5> in <module>
----> 1 [1, 2, 3] + 4

TypeError: can only concatenate list (not "int") to list

Listas anidadas

Como mencionamos anteriormente, una lista puede contener cualquier tipo de objeto. Esto incluye otra lista. Una lista puede contener sublistas, que a su vez pueden contener sublistas, y así sucesivamente.

lista = [1, [2, [3, 4], 5], 6]

lista[0]

1

lista[1]

[2, [3, 4], 5]

Si queremos acceder a un elemento de una sublista usaremos [][]

lista = [1, [2, [3, 4], 5], 6]

lista[1][0]

2

lista[1][1]

[3, 4]

lista[1][1][0]

3

Podemos anidar tantas listas como nuestro sistema soporte

Es importante mencionar que si usamos operadores en una lista con sublistas anidadas, estos solo se aplicaran a la primera, no lo haran de forma recursiva, y se deseariamos usarlos debemos aplicar el concepto de indexing

lista = [1, [2, [3, 4], 5], 6]

[3, 4] in lista

False

lista[1]

[2, [3, 4], 5]

[3, 4] in lista[1]

True

Las listas son mutables

Al contrario que los strings, los elementos de las listassi pueden modificarse

lista = ["texto1", "texto2", "texto3"]

lista[0]

'texto1'

lista[0] = "texto4"

lista

['texto4', 'texto2', 'texto3']

Si queremos tambien podemos eliminar elementos una lista

lista = ["texto1", "texto2", "texto3"]

del lista[0]

lista

['texto2', 'texto3']

Para realizar estas modificaciones tambien podemos usar los conceptos del indexing, slicing y stride.

lista

['texto1', 'texto2']

lista += ["texto3", "texto4", "texto5"]

lista

['texto1', 'texto2', 'texto3', 'texto4', 'texto5']

lista[0:3]

['texto1', 'texto2', 'texto3']

lista[0:3] = [1, 2, 3]

lista

[1, 2, 3, 'texto4', 'texto5']

Otra cosa interesante es que el numeros de elementos seleccionados no tiene que ser igual a los que se asigne

lista[0:3]

[1, 2, 3]

lista[0:3] = [1, 2]

lista

[1, 2, 'texto4', 'texto5']

lista[2:2] = [3, 4, 5]

lista

[1, 2, 3, 4, 5, 'texto4', 'texto5']

lista[0:6] = []

lista

['texto5']

Funciones #

Antes de continuar con el contenido del curso se me hace necesario tocar ya el tema de funciones. Hemos visto distintos tipos de datos anteriormente, pero ahora vamos a profundizar en una de las estructuras principales de python que son las funciones.

Una función va a consistir en un bloque de código que va encapsular una tarea específica o un grupo de tareas relacionadas. Las funciones nos permiten dividir programas complejos en fragmentos más pequeños y modulares, de manera que podamos volver a utilizar estos fragmentos de codigo en un momento determinado de modo tal que no tenemos que volver a implementarlo.

En este caso vamos a invocar una función que ya viene definida en python. Concretamente una que ya vimos antes de nombre len.

Vamos a comenzar declarando una variable y lo siguiente sera ver como podemos invocar una función.

variable = "Hola Python"

Para invocar la función debemos de poner el nombre de la función y entre parentesis ponemos los argumentos de la función. Esta función lo que hara es ejecutar una serie de lineas de codigo que estan definidas en alguna parte de python y nos devuelve el numero de caracteres que contiene nuestra variable.

len(variable)

11

Ahora el resultado que nos devuelve la función, podemos asignarlo a otra variable.

len_variable = len(variable)

print(len_variable)

11

La función que se muestra anterioremente forma parte de un conjunto de funciones que estan definidas en el interprete de Python y podemos utilizar siempre que lo necesitemos.

Para utilizar estas funciones no necesitamos conocer el detalle del código fuente que la implementa, únicamente necesitamos conocer:

  • Los argumentos recibe la función
  • Los valores que devuelve

Mas adelante veremos a detalle las funciones integradas de python.

Funciones Personalizadas #

Para poder definir funciones en python la sintaxis utilizada es la siguiente:

def <nombre_funcion>([<parámetros>]):
    <sentencia(s)>

Debemos comenzar utilizando la palabra clave def despues de un espacio ponemos el nombre_función que queremos definir y entre () los parametros que va a recibir nuestra función, la cual se va a traducir a los elementos que le vamos a proporcionar cuando la llamemos.

El elemento, <sentencia(s)>, se denomina cuerpo de la función. El cuerpo es el bloque de sentencias en Python que se ejecutará cuando se llame a la función. Cabe mencionar que el cuerpo de una función de Python se define por la sangría.

Vamos a comenzar definiendo nuestra función:

def mi_funcion(argumento1, argumento2):
    print(argumento1)
    print(argumento2)

Como podemos visualizar he definico una función de nombre mi_funcion que va a recibir 2 parametros argumento1 y argumento2 y el codigo que ejecutara sera con print imprimirme por pantalla primero el argumento1 y segundo el argumento2

Ahora para ejecutarla la función es super sencillo. La sintaxis debe ser la siguiente: <nombre_funcion>([<argumentos>]).

Cabe resaltar que Los <argumentos> son los valores que se pasan a la función. Se corresponden con los <parámetros> en la definición de la función que asignamos.

Por lo tanto para llamar a la función, deberiamos hacerlo de la siguente manera:

mi_funcion("Hola Python", "Adios Python")

Hola Python
Adios Python

Es importante mencionar que la ejecución de nuestro programa sera secuencial hasta que llegue a la función.

Para entendero mejor, supongamos que estoy defiendo un programa:

1.- Primero, ejecutar un print(“Curso Python”) 2.- Segundo, llamare a mi función antes declarada, no sin olvidar añadir los parametros que necesita 3.- Tercero, volvere a ejecutar un print(“Aprende Python”)

print("Curso Python")
mi_funcion("Hola Python", "Adios Python")
print("Aprendere Python")

Como resultado tendre que el interprete de python comenzara a ejecutar mi programa linea por linea.

Curso Python
Hola Python
Adios Python
Aprendere Python

Lo que quiero resaltar es que necesitamos crear funciones relacionadas con tareas especificas que realizen una acción particular, de tal modo que podamos volver a reutilizar.

Bueno por si habia duda tambien se pueden definir funciones que no reciban ningún argumento, pero los paréntesis siempre seran necesarios. Tanto en una definición de función como una llamada a una función deben incluir siempre paréntesis, incluso si están vacíos.

def mi_funcion2():

    print("Hola Python")
    print("Adios Python")

De tal modo que para ahora llamar a mi función solo debo de poner el nombre de las función y los ().

mi_funcion2()

Hola Python
Adios Python

Argumentos de las Funciones #

Los argumentos que podemos proporcionarle a una función en Python pueden ser de diferentes tipos.

Argumentos Posicionales

Como vimos anteriormente la forma más sencilla de pasar argumentos a una función en Python es con argumentos posicionales (llamados tambien argumentos requeridos). En la definición de la función, debe especificarse una lista de parámetros separada por comas dentro de los paréntesis.

def mi_funcion(argumento1, argumento2, argumento3):
    print(argumento1)
    print(argumento2)
    print(argumento3)

Los argumentos que le proporcionamos en la invocación de la función debe respetar el orden y el número de parámetros definidos.

mi_funcion("Hola Python", "Adios Python", "Grande Python")

Hola Python
Adios Python
Grande Python

Si yo trato de llamar a la función, pero en lugar de pasarle los tres argumentos solo le paso dos.

mi_funcion("Hola Python", "Adios Python")

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-c560729c0eac> in <module>
----> 1 mi_funcion("Hola Python", "Adios Python")

TypeError: mi_funcion() missing 1 required positional argument: 'argumento3'

Como vemos lo que ocurre es que el interprete de python me dara un error, donde me dira que a la función que defini previamente con tres argumentos me ha faltado ponerle un elemento posicional correspondiente a argumento3. Ya que ha identificado un valor para argumento1 y argumento2, pero no para argumento3. Y como es un argumento posicional es obligatorio que ponga el mismo numero de argumentos como parametros definamos en nuestra función.

Los parámetros se comportan como variables que estan definidas de manera local a la función (únicamente en el cuerpo de la función). Cuando se invoca la función, los argumentos que se le proporcionan se asignan a los parámetros en el orden en el que estuvieran definidos. Esto quiere decir que los parametros que yo estoy poniendo en la definición de la función se van a comportar como variables dentro del cuerpo de la función, pero no fuera del cuerpo.

Vamos a ver un ejemplo para entender esto mejor:

Primero voy a definir una función que no recibira ningun argumento, lo que hara sera simplemente crear una variable var que le asignara una cadena de texto y me lo imprimira por pantalla.

def mi_funcion():
    var = "mi variable 'var' dentro de la funcion"
    print(var)

Ahora voy a definir otra variable con el mismo nombre var fuera de la función y le voy a asignar una cadena de texto. Seguidamente llamara a mi función previamente creada y finalmente imprimire por pantalla la variable var.

var = "variable 'var' fuera de mi función"
mi_funcion
print(var)

Ahora al ejecutar esto lo que me muestra es:

variable 'var' dentro de la funcion
variable 'var' fuera de la funcion

Como podemos ver lo primero que me imprime el programa es variable 'var' dentro de la funcion y despues variable 'var' fuera de la funcion.

Esto ocurre por que tanto los parametros y variables que definamos dentro de una función van a estar en el contexto local de esa función y no va a afectar a lo que hayamos definido fuera. Por ello aunque yo haya definido una variable con el mismo nombre, para python son variables diferentes ya que se encuentran en contextos diferentes, una dentro de la función y otra fuera de esta.

Argumentos de Palabras Clave

Otra manera de invocar una función en Python es indicando los argumentos de la forma <palabra clave>=<valor>. En ese caso, cada <palabra clave> debe coincidir con un parámetro en la definición de la función.

Veamoslo mejor en un ejemplo para entenderlo bien:

Comencemos definiendo una función

def mi_funcion(argumento1, argumento2):
    print(argumento1)
    print(argumento2)

Lo siguiente que hare sera invocar la función pero en este caso le pasare argumentos de palabra clave en lugar de posicionales.

Voy a definir dos variables

variable1 = "Hola Python"
variable2 = "Adios Python"

Ahora llamare a mi función, pero en lugar de pasarle las variables como argumentos posicionales, que seria algo como mi_funcion(variable1, variable2). Lo que hare sera indicarle el nombre del parametro que quiero que este asociado con el argumento que le pase.

mi_funcion(argumento1=variable1, argumento2=variable2)

Hola Python
Adios Python

Si quisiera podria invertirlo y el resultado me lo sacaria alreves.

mi_funcion(argumento1=variable2, argumento2=variable1)

Adios Python
Hola Python

Una cosa que es importante sobre los argumentos de palabras clave es que no tenemos que respetar el orden de los parametros para pasarle los argumentos.

Aunque en la definición de nuestra función pusimos como primer parametro argumento1 y segundo argumento2. Como yo le digo a que valor estan asignados, puedo cambiar el orden y no necesitamos que esten en el mismo orden que en la definición.

mi_funcion(argumento2=variable1, argumento1=variable2)

Adios Python
Hola Python

Otra cosa que debemos tener en cuenta es que no podemos poner el nombre de un argumento que no se encuentre definido como parametro de la función

mi_funcion(argumento1=variable1, argumento3=variable2)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-96e6349729cf> in <module>
----> 1 mi_funcion(argumento1=variable1, argumento3=variable2)

TypeError: mi_funcion() got an unexpected keyword argument 'argumento3'

Logicamente python me dara un error ya que el argumento3 no se encuentra en la definición de nuestra función.

De la misma manera tenemos que respetar el numero de argumentos que le pasamos al invocar nuestra función. De otra manera este nos dara un error de que falta un argumento posicional.

mi_funcion(argumento1=variable1)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-20-c46543542516> in <module>
----> 1 mi_funcion(argumento1=variable1)

TypeError: mi_funcion() missing 1 required positional argument: 'argumento2'

Otra de las cosas interesantes que nos permite hacer Python, es la combinación argumentos posicionales y de palabra clave en la misma llamada a una función. En estos casos, siempre los argumentos posicionales deben indicarse primero.

def mi_funcion(argumento1, argumento2):
    print(argumento1)
    print(argumento2)

variable1 = "Hola Python"
variable2 = "Adios Python"


mi_funcion(variable1, argumento2=variable2)

Hola Python
Adios Python

Como podemos ver que efectivamente el programa se nos ejecuta correctamente.

Pero ahora que pasa si yo pongo el segundo parametro comi posicional.

mi_funcion(argumento1 = variable1, variable2)
    mi_funcion(arg1=var, var2)
                             ^
SyntaxError: positional argument follows keyword argument

Pues esto me dara un error que me dira que hay un argumento posicional que sigue a un argumento de palabra clave. Entonces necesariamente tiene que ser alreves.

Parametros con Valores por defecto

Si especificamos un parámetro en la definición de una función en Python utilizando la forma <nombre>=<valor>, entonces <valor> se convierte en un valor por defecto para ese parámetro. A eso denominamos parametros por defecto.

Vamos a definir una función, donde le pasaremos dos parametros y que el segundo correspondera a uno por defecto.

def mi_funcion(argumento1, argumento2="Valor por defecto"):
    print(argumento1)
    print(argumento2)

Lo que me permite es jugar con el numero de argumentos que le paso a la función, ya que esta vez puedo pasarle menos argumentos de los que estan definidos al invocar a la función

mi_funcion("Hola Python")

Hola Python
Valor por defecto

Lo que hace la función es decir que el primer argumento necesita si o si que me pase un valor, entonces como ya se lo pasamos, esto lo asignara a argumento1 y nos los sacara por pantalla este primer argumento. Ahora en lo que corresponde al segundo parametro si le pasamos algo lo asignara a argumento2, de lo contrario cogera el valor que tiene por defecto y como en este caso no le pasamos nada lo que hizo fue imprimirnos el valor por defecto.

Pero si ahora yo le indico un valor. Como esta vez le estamos asignando un valor al argumento2, esta vez no necesitara el valor por defecto y por lo tanto lo descarta y imprimira el valor que le hayamos pasado.

mi_funcion("Hola Python", "Adios Python")

Hola Python
Adios Python

Sentencia Return

Las funciones en Python pueden retornar un valor despues de haber ejecutado las sentencias de código definidas. Para devolver un valor, se debe utilizar la palabra return dentro del cuerpo de la función.

Ahora hay que tener en cuenta algunas cosas cuando utilizamos return:

  • Cuando se ejecuta return en Python, el intérprete termina inmediatamente la ejecución de la función y regresa a la línea de código desde dónde la hubiésemos invocado.

Vamos a verlo en un ejemplo mas practico.

Comenzamos definiendo una función simple donde ejecutaremos un print de un texto, despues usaremos la sentencia return y finalmente volveremos a ejecutar otro print.

def mi_funcion():
    print("Sentencia 1 dentro de mi funcion")
    return
    print("Sentencia 2 dentro de mi funcion")

Ahora escribiremos codigo fuera de nuestra función, donde primero haremos un print, despues llamaremos a la función que creamos y finalmente usaremos otro print.

print("Sentencia 1 fuera de mi funcion")
mi_funcion()
print("Sentencia 2 fuera de mi funcion")

Al ejecutar esto lo que pasara es que se ejecutara la primera linea, despues ejecutara nuestra función, la cual tiene tres lineas donde se ejecutara la primera linea con normalidad, pero después en la segunda linea al estar la sentencia return, terminara la ejecución de nuestra función sin ejecutar la tercera linea y retornara la ejecución a donde se ejecuto la función y en consecuencia se ejecutara el print de la ultima linea.

Sentencia 1 fuera de mi funcion
Sentencia 1 dentro de mi funcion
Sentencia 2 fuera de mi funcion
  • Si definimos la palabra return de la forma return <valor> se retornará el <valor> especificado en la llamada a dicha función.
def mi_funcion():
    return "Valor de la funcion"
    print("Esta linea nunca podra ejecutarse")

Esto nos permite que al invocar nuestra función podamos recibirla en una variable. Y lo que hara la función sera ejecutarme el return y devolverme el resultado en la variable mi_variable, que en consecuencia al imprimirla me deolvera la cadena de texto que esta asociada al return.

Cabe mencionar que el print de la función no se ejecutara debido a que debemos recordar que el return termina la ejecución de la función

mi_variable = mi_funcion()

print(mi_variable)

Valor de la funcion

Tambien podria ejecutar mi función sin asignarsela a ninguna variable.

mi_funcion()

Valor de la funcion

Ojito una cosa muy interesante tambien es que podria aplicar a esta función. Ya que nos devuelve una cadena de texto, podria aplicar conceptos como el de slide, slicing y stride

mi_funcion()[0:5]

Valor
  • Si no indicamos el término <valor> en la sentencia return se devuelve un tipo de datos conocido como None
def mi_funcion():
    return

variable = mi_funcion()

print(variable)

None
  • Podemos utilizar la sentencia return para devolver varios valores utilizando la sintaxis return <valor1>,<valor2>,...,<valorn>

Supongamos que definimos una función que queremos que retorne tres cadenas de texto.

def mi_funcion():
    return "texto1","texto2","texto3"

Y cogeria estos valores, definiendo tres variables e igualandolas a la función

variable1,variable2,variable3 = mi_funcion()

Si ahora imprimo las variables

print(var1)

print(var2)

print(var3)

texto1
texto2
texto3

Docstrings

Los docstring los utilizamos para proporcionar la documentación de una función. Como el propósito de la función, los argumentos que va a tomar, información sobre los valores de retorno, o cualquier otra información que consideremos útil.

Cuando la primera declaración en el cuerpo de una función en Python es un string de la forma """texto""", esto es lo que se conoce como docstring.

Aqui tenemos un ejemplo de como lo podemos definir:

def mi_funcion():
    """Esto es un docstring de nuestra función"""
    print("Hola Python")

Tambien podemos definir docstring de varias lineas.

def mi_funcion2(argumento1=4, argumento2=8):
    """Este es un docstring de varias líneas.

    Argumentos:
    argumento1 -- primer argumento de la funcion (valor por defecto 4)
    argumento2 -- segundo argumento de la funcion (valor por defecto 8)
    """
    return

Funciones Propias de Python

El intérprete de Python tiene una serie de funciones que están siempre disponibles. A continuación se enumeran en orden alfabético.

    Lista de Funciones    
abs() delattr() hash() memoryview() set()
all() dict() help() min() setattr()
any() dir() 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()  

Estas son todas las funciones disponibles que estan integradas en python. A continuación veremos algunas de las mas importantes, pero no esta de mas practicar para ver de que trata cada una de ellas.

Comenzaremos con la función help que se utiliza para mostrar la documentación de un objeto. Si la invocamos sin asignarle ningun objeto y me saldra una sesión interactiva donde podemos introducir algo sobre lo que queremos saber su información, en este caso introduciremos len.

help()

Welcome to Python 3.10's help utility!

If this is your first time using Python, you should definitely check out
the tutorial on the Internet at https://docs.python.org/3.9/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> len
Help on built-in function len in module builtins:

len(obj, /)
    Return the number of items in a container.

Como vemos despues de introducir la función len nos dice que es una función que nos retorna el numero de elementos que tiene un objeto que le proporcione como elemento.

Continuando con otras funciones vamos a utilizar help ahora con print

help(print)

Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

Probemos entonces. Aqui estariamos utilizando los valores por defecto.

print("Hola Python")

Hola mundo

Ahora tambien podemos pasarle dos valores, pueden ser de cualquier valor.

print("Soy el numero", 1)

Soy el numero 1

Probemos ahora la opción sep que nos muestro al usar help. Lo que hara sera separarnos los valores por lo que introduzcamos en sep

print("Soy el numero", 1, sep=":")

Soy el numero:1

Continuemos con otras funciones importantes que ya habiamos visto un poco antes. Concretamente seria int, str y float

Vamos a definir primero una serie de variables.

texto = "10" # esta variable es una string
numero_int = 10 # esta variable corresponde a un int
numero_float = 10.6 # esta variable es un float

Seguidamente vamos a probar estas funciones:

Si usamos int en la variable de texto esta nos la devolvera como entero.

int(texto)

10

Y si ahora usamos la función str sobre el entero, pues nos devolvera la variable transformada a string.

str(numero_int)

'10'

Aplicando lo mismo con un float nos devolveria el resultado en flotante.

float(numero_int)

10.0

Otra de las funciones importantes es type que lo que hace es retornar el tipo del objeto que le proporcionamos como argumento.

Veamosla a continuación:

type(10)

int

type("10")

str

type(10.5)

float

Podriamos hacerlo para cualquier tipo de dato.

lista = [1, 2, 3, 4]

type(lista)

list

Tenemos tambien a la función id que la vimos anteriormente. Y como mencioamos al pasarle un objeto nos dara como valor un numero asociado a la porción de memoria que este ocupa en la memoria.

texto = "Hola Python"

id(texto)

139906352396400

Veamos ahora la función exec, que ejecuta el codigo que le pasemos como argumento en formato string.

Definimos una variable que contiene una sentencia print. Que si la ejecutamos con exec nos va a relizar la ejecución de lo que contenia nuestra variable.

variable = "print('Hola Python')"

exec(variable)

Hola Python

Tambien podemos tener funciones como round que sirve para redondear un valor, max y min para obtener el valor maximo y minimo y range para obtener un rango de numeros asociados.

Lo recomendable es hechar un ojo a cada una de ellas para saber en que consiste cada una, pero cabe mencionar que la mayoria de ellas las veremos a lo largo del curso.

Tuplas #

Una tupla viene a ser un objeto identico a una lista excepto por dos propiedades:

  • Definen una colección ordenada de objetos, sin embargo utilizan () en la sintaxis (objeto1, objeto2, …, objetojn)

  • A diferencia que las lista, las tuplas son tipos de datos inmutables

La representación dentro de python con el tipo de dato tuple

Veamoslo a continuación

tupla = (1, 2, 3, 4, 5)

type(tupla)

tuple

Se pueden aplicar todas las funciones que aplicabamos a las listas.

print(tupla)

(1, 2, 3, 4, 5)

len(tupla)

5

Funcionamiento de las Tuplas

Podemos mezclar todo tipo de datos en una tupla, al igual que podemos usar conceptos como slide, stride y slicing

tupla = (1, 2, 3, "texto1", "texto2", "texto3")

print(tupla)

(1, 2, 3, 'text1', 'text2', 'text3')

tupla[0:4]

(1, 2, 3, text1)

Como mencionaba antes y hay que tenerlo muy presente es que las tuplas no pueden modificarse, ya que son inmutables y si tratamos de hacerlo python nos dara un error.

tupla = (1, 2, 3, "texto1", "texto2", "texto3")

tupla[2] = "texto0"

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-6b0bedb66139> in <module>
----> 1 tupla[2] = "texto0"

TypeError: 'tuple' object does not support item assignment

Ahora seguro te preguntaras, si ya tenemos listas que son un objeto super potente en python y a diferencia de las tuplas, estas si podemos modificarlas. Entonces ¿Por que usaria una tupla?

Pues esto lo veremos a continuación.

Cuando utilizar una tupla en vez de una lista

Existen algunos casos donde es mas recomendable usar tuplas en lugar de lista.

  • Cuando se manipula una tupla, la ejecución del programa es mucho mas rapida. Esto cuando utilizamos una lista o tupla con muchos elementos.

  • El uso de una tupla protege contra una modificación accidental

  • Existe un tipo de dato llamado diccionario que lo veremos un poco mas adelante, que requiere como uno de sus componentes un valor inmutable. Por ello una tupla puede utilizarse para este proposito mientras que una lista no.

  • Podemos usar el empaquetado y desempaquetado que lo veremos un poquito mas adelante

Para cualquier otro caso de uso que no sean los que hago mención, es mucho mas recomendable el uso de una lista

Tuplas y tipos de datos Numericos

Debemos de tener cuidado al momento que definimos una tupla con un único elemento de tipo numérico. Python puede llegar a interpretar los paréntesis como parte de la expresión matemática y definirlo como un tipo de dato numérico en lugar de una tupla.

tupla = (4)

tupla

4

type(tupla)

int

Para solucionar esto, podemos hacer uso de la sintaxis (numero,)

tupla = (4,)

tupla

(4,)

type(tupla)

tuple

Packing y Unpacking - Empaquetado y Desempaquetado

Anteriormente pudimos ver como una tupla con varios elementos puede asignarse a una unica variable.

mitupla = (1, 2, 3, 4)

No obstante, una tupla nos permite usar la estructura de empaquetado y desempaquetado. Esto quiere decir que podemos asignar los elementos de una tupla a distintas variables simultaneamente.

mitupla = (1, 2, 3, 4)

print(mitupla)

(1, 2, 3, 4)

numero1, numero2, numero3, numero4 = mitupla

De modo que si ahora yo muestro las variables, corresponderan a los que teniamos en la tupla.

print(numero1)

1

print(numero2)

2

print(numero3)

3

print(numero4)

4

Una cosa a tener en cuenta es que al realizar este proceso, el numero de variables que pongamos deben de coincidir con el numero de elementos de la tupla

Ya que si asigno un valor menor o mayor, python me mostrara un error.

numero1, numero2, numero3 = mitupla

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[7], line 2
      1 # El número de variables debe coincidir con el número de elementos de la tupla
----> 2 numero1, numero2, numero3 = tupla

ValueError: too many values to unpack (expected 3)

Este concepto de desempaquetado o Unpacking tambien nos permite devolver varios elementos en una función y asignarlos a varias variables.

def funcion():

    return 1,2

func()

(1, 2)

numero1, numero2 = func()

print(numero1)

1

print(numero2)

2

Otra cosa a mencioanr que es bastante interesante es que podemos definir una tupla sin usar (). Es algo muy raro de python que quiza pueda causar confusión, por ello recomiendo siempre mantener buenas practicas y usar ()

tupla = 1, 2, 3

type(tupla)

tuple

Diccionarios #

Los diccionarios son un tipo de dato complejo y particular en Python que corresponden con una colección de elementos clave-valor. Cada elemento clave-valor asocia la clave con un valor determinado.

Para representar los diccionarios dentro de python lo hacemos con el tipo de dato dict. La sintaxis utilizada para definir diccionarios es la siguiente: {clave:valor1, clave2:valor2, ..., claven:valorn}

Como podemos observar a diferencias de las listas y las tuplas usamos las {}

Veamos a continuación un ejemplo:

diccionario = {
    "Nombre":"firtsmiracle",
    "Curso":"Python",
    "Idioma":"Español",
    "Nivel":"Todos los Niveles"
}

Como vemos los diccionarios nos permiten especificar un contexto sobre cada uno de los objetos, y de esta manera podemos tener una referencia de los objetos contenidos en la clave.

Al imprimirlo tendriamos lo siguiente:

print(diccionario)

{'Nombre': 'firtsmiracle', 'Curso': 'Python', 'Idioma': 'Español', 'Nivel': 'Todos los Niveles'}

y si le ahora usamos la función integrada type podemos ver que efectivamente nuestro dato corresponde a un diccionario

type(diccionario)

dict

Ahora tambien existe una forma de definir un diccionario, aunque es un poco inusual. Para ellos la sisntaxis que debemos usar es definir una variable y usaremos la función dict que recibira una serie de argumentos que seran la clave y el valor. Pero esta vez la clave no sera declarada como un string, sino como un argumento y la igualamos al valor que queremos que tenga.

diccionario2 = dict(
    Nombre="firtsmiracle",
    Curso="Python",
    Idioma=Español",
    Nivel="Todos los Niveles"
)

Y si ahora sacamos este diccionario por pantalla, sera exactamente el mismo que definimos previamente.

print(diccionario2)

{'Nombre': 'firtsmiracle', 'Curso': 'Python', 'Idioma': 'Español', 'Nivel': 'Todos los Niveles'}

Acceso a los Elementos de un Diccionario #

A diferencia de las tuplas y las listas, en los diccionarios no podemos acceder utilizando un indice. Los valores se acceden utilizando el nombre de las claves entre [].

Vemoslo nuevamente en un ejemplo a continuación, para ello usaremos el diccionario que previamente habiamos definido.

diccionario = {
    "Nombre":"firtsmiracle",
    "Curso":"Python",
    "Idioma":"Español",
    "Nivel":"Todos los Niveles"
}

Ahora supongamos que queremos acceder a la primera clave de mi diccionario. Lo que haria unicamente seria poner entre [] el nombre de la clave.

diccionario['Nombre']

'firtsmiracle'

Lo mismo si quisieramos acceder a otra clave.

diccionario['Curso']

'Python'

Sim embargo como antes mencionamos, que si queremos hacer lo mismo pero usando un indice, python nos dara un error, ya que nuevamente debemos recalcar que unicamente podemos acceder usando el nombre de las claves.

diccionario[0]

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-10-d5a2f4e83513> in <module>
----> 1 diccionario[0]

KeyError: 0

Otra cosa muy importante a tener en cuenta es que podemos usar cualquier objeto inmutable como clave de un diccionario. Estos incluyen a las listas, numeros, tuplas, strings entre otros.

diccionario2 = {
    0: "numero cero",
    1: "numero uno",
    2: "numero dos",
    3: "numero tres"
}

Si ahora queremos acceder a uno de los valores tenemos que hacerlo a traves de su clave, que en este caso corresponde a un objeto inmutable que es un numero. Entonces debemos acceder de la siguiente forma:

diccionario2[0]

'numero cero'

Lo mismo podriamos hacerlo pero esta vez usando un tupla.

diccionario3 = {
    ("numero", 1): "primer numero",
    ("numero", 2): "segundo numero",
    ("numero", 3): "tercer numero"
}

Vemos que esta vez como clave usamos una tupla, y si queremos acceder a uno de los elementos pues debemos hacerlo a traves de la tupla. Raro pero podemos hacerlo.

diccionario3[("numero", 1)]

'primer numero'

Elementos de un Diccionario #

Los diccionarios son objetos que pueden modificarse y no se respeta el orden de los elementos, por este motivo es que accedemos a traves de una clave y no mediante un indice.

Veamoslo a continuación de manera practica:

Primero definamos nuestro diccionario, usaremos el que ya teniamos para efectos practicos.

diccionario = {
    "Nombre":"firtsmiracle",
    "Curso":"Python",
    "Idioma":"Español",
    "Nivel":"Todos los Niveles"
}

Ahora para poder modificar un elemento, debemos usar la clave que deseamos cambiar, de la misma manera que lo haciamos con los indices. Para este caso en concreto modificaremos las claves Nombre y Curso.

diccionario["Nombre"] = "Milagro"

diccionario["Curso"] = "Bash"

print(diccionario)

{'Nombre': 'Milagro', 'Apellido': 'Bash', 'Idioma': 'Español', 'Nivel': 'Todos los Niveles'}

Una cosa interesante que debemos tener en cuenta sobre los diccionarios es que podemos añadir nuevos elementos en la estructura cuando lo necesitemos.

De la misma manera qu accediamos a las claves para poder modificarlas, tambien podemos hacer el proceso similar para añadir elementos, solo que en este caso al no existir la clave en el diccionario este nos la crea en conjunto con su contenido.

print(diccionario)

{'Nombre': 'Milagro', 'Curso': 'Bash', 'Idioma': 'Español', 'Nivel': 'Todos los Niveles'}

diccionario["Duración"] = "Constantemente"

print(diccionario)

{'Nombre': 'Milagro', 'Apellido': 'Bash', 'Idioma': 'Español', 'Nivel': 'Todos los Niveles', 'Duración': "Constantemente"}

Hay que tener en cuenta que los diccionarios nos permiten asignar diferente tipos de datos. Esto incluye strings, listas, tuplas y exacto tambien diccionarios. Esto quiere decir que podemos insetar un diccionario dentro de otro.

diccionario = {
    "int":20,
    "str":"Hola Python",
    "lista":[1, 2, 3, 4],
    "tupla":(1, 2, 3, 4),
    "dict":{"num1":"numero1", "num2":"numero2"}
}

Si ahora probamos a acceder a algunos elementos.

diccionario["tupla"]

(1, 2, 3, 4)

diccionario["dict"]

{'num1': 'numero1', 'num2': 'numero2'}

Una cosa a tener en cuenta es que las claves no tiene que ser el mismo tipo de dato.

Me refiero a que podemos definir una clave como int y asignarle un string, como vemos a continación.

diccionario = {
    1:"Este es mi primer numero",
    "dos":"Este es mi segundo numero",
    ("tres",):"Este es mi tercer numero"
}

Si ahora deseamos mostrarlos por pantalla.

diccionario[1]

'Este es mi primer numero'

diccionario["dos"]

'Este es mi segundo numero'

diccionario[("tres",)]

'Este es mi tercer numero'

Otro punto a tener en cuenta es que la restricción cuando utilizamos diccionarios, es que no puede haber dos claves con el mismo nombre.

diccionario = {
    "nombre":"firtsmiracle",
    "nombre":"firtsmiracle2"
}

En este caso estamos usando como clave dos veces a nombre y debido a esto lo que sucede es que si mostramos por pantalla nuestro diccionario unicamente nos mostrara la clave final que nombramos y no nos mostrara la primera o las anteriores creadas ya que sobrescribe la clave.

diccionario

{'nombre': 'firtsmiracle2'}

Operaciones con Diccionarios #

Al igual que hacemos con las listas y los demas de tipos de datos complejos, podemos utilizar algunos de los operadores presentados en los temas anterior con los diccionarios.

diccionario1 = {
    "clave1": "valor1",
    "clave2": "valor2"
}

diccionario2 = {
    "clave3": "valor3",
    "clave4": "valor4"
}

Podemos aplicar algunos operaciones como las de identidad.

diccionario1 is diccionario2

False

diccionario1 == diccionario2

False

Pero en el caso de operadores aritmeticos, estos no podemos usarlos ya que nos da un error.

diccionario1 + diccionario2

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-51-9a6dceb2d25d> in <module>
----> 1 diccionario1 + diccionario2

TypeError: unsupported operand type(s) for +: 'dict' and 'dict'

Sets #

Los sets son un tipo de datos que nos permite almacenar múltiples elementos en una misma variable. A diferencia de las listas, la colección de elementos que forman un set:

  • No se pueden indexar
  • No respetan un orden
  • No pueden contener valores duplicados

Los sets se representan con el tipo de dato set. La sintaxis que se utiliza para definir un set en Python es: {valor1, valor2, …, valorn}.

Vamos a definir un set a continuación para poder entenderlo de una mejor manera.

lenguajes = {"python", "rust", "javascript"}

print(lenguajes)

{'python', 'rust', 'javascript'}

type(lenguajes)

set

Funcionamiento de un set #

Debido a sus caracteristicas, suele utilizarse para casos de uso muy específicos, como eliminar elementos duplicados de una lista o implementar algunas operaciones matemáticas como la intersección de dos conjuntos.

lenguajes = {"python", "rust", "javascript"}

miset[0]

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-97dccbd19ab1> in <module>
      1 # Los elementos de un set no se pueden indexar
----> 2 lenguajes[0]

TypeError: 'set' object is not subscriptable

Como observamos si tratamos de indexar, no nos es posible. La pregunta seria entonces si no podemos ingresar a sus elementos para que nos sirve?.

Pues una de ellas seria que si tenemos la necesidad de eliminar elementos repetidos de una lista que en muchos casos nos va a pasar, podemos hacerlo haciendo uso de la función set() y con ella quitamos todos los elementos duplicados.

lenguajes = ["python", "rust", "javascript", "python", "php", "nodejs", "javascript", "python", "C", "php"]

set(lenguajes)

{'python', 'rust', 'javascript', 'php', 'nodejs', 'C'}

Ahora podemos ver que tenemos que eliminamos los elementos repetidos, pero ahora diras, perfecto se elimino pero ahora tengo un set y yo quiero una lista. Pues podemos utilizar el mismo concepto para convertir el resultado de nuestro set a una lista, haciendo uso de la función list.

lenguajes = ["python", "rust", "javascript", "python", "php", "nodejs", "javascript", "python", "C", "php"]

lenguajesUnicos = list(set(lenguajes))

print(lenguajesUnicos)

['python', 'rust', 'javascript', 'php', 'nodejs', 'C']

Frozenset #

Es igual que un set, pero con la diferencia de que este es inmutable. No es un tipo de dato relevante, pero no esta de mas mencionarlo.

frozset = frozenset({"python, php, javascript"})

print(frozset)

frozenset({'python, php, javascript'})

type(frozset)

frozenset

NoneType #

La palabra clave None es un objeto de la clase NoneType que se utiliza para definir una variable nula o un objeto vacío.

Podemos asignar None a cualquier variable, pero no se podemos crear objetos NoneType.

variable = None

print(variable)

None

type(None)

NoneType

Usamos este tipo de dato cuando no queremos retornar nada o cuando tenemos una variable a la que no asignesmos ningun valor, nos encontraremos muchas vences con este tipo de dato.

Funcionamiento #

Debemos tener en cuanto algunas cosas importantes sobre None, las cuales son:

  • None no es igual que False
  • None no es 0
  • None no es un string vacío
  • Cuando comparamos None con cualquier cosa devuelve False excepto con None
variable = None

variable is None

True

variable == None

True

variable is False

False

variable is True

False

variable == False

False

variable == 0

False

variable == ""

False

Como podemos ver si comparamos el None con cero o una cadena vacia nos devuelve False, puesto que no es lo mismo y de igual manera si comparamos con cualquier otra cosa nos devolvera False. El unico caso en el que nos devuelve True es cuando lo comparamos con el propio None.

Estructuras de Control de Flujo #

Todo lo que hemos visto hasta el momento han sido elementos que se ejecutan de manera secuencial y en el orden especificado.

Sin embargo, cuando estamos programando con frecuencia se necesita cambiar el control del flujo de ejecución de las sentencias y realizar acciones como: saltarse alguna sentencia, ejecutar una serie de sentencias muchas veces repetidamente, o elegir entre conjuntos alternativos de sentencias a ejecutar.

Justo aqui es donde entran en juego las estructuras de control de flujo, ya que nos permiten modificar el flujo de ejecución de un programa.

Sentencia If, elif y else # {#sentencia-if,-elif-y-else}

Sentencia If #

La sentencia if es una de las estructuras más importantes de cualquier lenguaje de programación.

Esta estructura nos permite implementar sentencias condicionales dentro de nuestro programa.

La sintaxis utilizada para definir la sentencia if es la siguiente:

if expresión:
    sentencia(s)

expresión: Se evalua en un contexto booleano, cuyo resultado debe devolver True o False.

sentencia(s): Es el bloque de sentencias que se ejecutarán cuando el resultado de evaluar la expresión sea True, en caso contrario se omite.

Veamos a continuación un caso practico para entenderlo mejor.

Primero definamos dos variables y les asignaremos valores numericos.

numero1 = 5

numero2 = 10

Seguidamente vamos a definir una expresión que en este caso al cumplirse nos devolvera True

numero1 < numero2

True

Ahora vamos a usar la sentencia if con la expresión antes creada. Donde al cumplirse la expresión nos imprima por pantalla dos cadenas de texto.

if numero1 < numero2:

    print("Primera sentencia")

    print("Segunda sentencia")

Primera sentencia
Segunda sentencia

Efectivamente ya que el numero1 es mayor al numero2, nos valida como True la condición y nos mostrara las cadenas en pantalla.

Pero si ahora modificamos el valor de la variable numero1 y volvemos a validar la expresión usando la sentencia if, no nos imprimira las cadenas puesto que ahora la condición no se cumple.

numero1 = 15

if numero1 < numero2:

     print("Primera sentencia")

    print("Segunda sentencia")

Algo muy importante! es que en Python todo el codigo que sea local a una estructura,ya sea una función o una estructura de control como if, debe esta “identado”, es decir, respetar la sangría.

Una de las cosas super interesantes de esta sentencia de control de flujo es que podemos utilizar casi cualquier tipo de operador, tipo de dato y expresión siempre y cuando el resultado sea un valor booleano True o False.

En este caso usaremos una lista para ejecutar la sentencia.

listaAlumnos = ["juan", "pablo", "lucas"]

if "juan" in listaAlumnos:

    print("El alumno se encuentra en la lista")

El alumno se encuentra en la lista

Podriamos hacer lo mismo, pero esta vez a partir de una tupla.

Numeros = (1, 2, 4, 5, 6, 7, 8)

if 4 in Numeros:

    print("El numero se encuentra en la tupla")

El numero se encuentra en la tupla

Clausula Else #

Hay ocasiones donde nos encontraremos con casos en los que quedremos que una estructura ejecute unas sentencias si la expresión es True pero además, que ejecute otras sentencias distintas si la expresión es False. Para este tipo de casos se utiliza la cláusula else.

La sintaxis que debemos utilizar es la siguiente:

if <expresión>:
    <sentencia(s)>
else:
    <sentencia(s)>

A continuación vamos a mostrarlo en un ejemplo:

numero1 = 4

numero2 = 8

if numero1 < numero2:

    print("Ejecuta la sentencia si es True")

else:

    print("Ejecuta la sentencia si es False")

Ejecuta la sentencia si es True

Como vemos al cumplirse la condición, nos imprime el print dentro del if, pero si ahora modificamos la condición en sentido contrario, esta al no cumplirse nos devolvera un False y por lo tanto se ejecutara la condición definida en el else.

numero1 = 4

numero2 = 8

if numero1 > numero2:

    print("Ejecuta la sentencia si es True")

else:

    print("Ejecuta la sentencia si es False")

Ejecuta la sentencia si es False

Clausula Elif #

Ahora que pasaria si queremos implementar una estructura condicional que requiera múltiples evaluaciones de varias expresiones para tomar la decisión de qué código ejecutar. Para estos casos específicos podemos utilizar la cláusula elif.

La sintaxis que debemos utilizar para definir la cláusula elif dentro de una estructura if es esta:

if <expresión>:
    <sentencia(s)>
elif <expresión>:
    <sentencia(s)>
elif <expresión>:
    <sentencia(s)
...
else:
    <sentencia(s)>

Veamos en un caso practico a continuación.

alumnos = ["Peter", "Pablo", "Juan", "Scarlet"]

if "Pedro" in alumnos:

    print("Hola alumno Pedro")

elif "Nicolas" in alumnos:

    print("Hola alumno Nicolas")

elif "Maria" in alumnos:

    print("Hola alumna Maria")

elif "Scarlet" in alumnos:

    print("Hola Scarlet")

else:

    print("El alumno no se encuentra en la lista")

Hola Scarlet

Como vemos en nuestro programa, definimos una lista de alumnos y realizamos multiples evaluaciones con el uso de elif, de modo que el programa recorrera cada una de estas hasta que alguna se cumpla y nos devolvera el resultado de validar esa condición.

Sentencia if en una linea #

Python nos permite utilizar una sintaxis específica para implementar sentencias if en una sola línea de código. Sin embargo, el uso de esta opción no es tan recomendable debido a que puede aumentar la complejidad en la lectura del código.

Para ello solo debemos establecer una condición y seguidamente debemos separar cada sentencia que queremos ejecutar con ;.

if 20 > 10: print("Primera sentencia");print("Segunda sentencia")

Primera sentencia 
Segunda sentencia

Operador Condicional #

Python tambien soporta una construcción más relacionada con la sentencia if que puede resultarnos muy interesante para determinados casos. A esta construcción se le denomina operador condicional.

La sintaxis es la siguiente:

<expresión1> if <expresión_condicional> else <expresión2>

Esto nos permite simplificar el código que utilizamos para determinadas tareas como, asignar un valor a una variable en función de una condición o imprimir valores por pantalla.

Viendolo de manera practica.

Supongamos queremos asignar un valor en función al nombre que nos de el usuario, para ello podriamos crear un codigo que nos lo realize pero este tendria varias lineas.

nombre = "Juan"

if nombre == "Juan":
  edad = 18
else:
  edad = 10

print(edad)

18

Pero si usamos el operador condicional, podriamos simplificar todas esas lineas de codigo y ejecutarla en una sola.

nombre = "Juan"

edad = 18 if nombre == "Juan" else 10

print(edad)

18

Como vemos en ambos casos obtenemos el mismo resultado, pero haciendo uso de este operador optimizamos nuestro codigo de tal modo que podemos simplicarlo, y esto nos resulta muy conveniente.

De la misma manera podemos usar este operador para en vez de asignar, mostrar resultados por pantalla.

dia="sabado"

print("Voy a estudiar python" if dia=="sabado" else "tengo que trabajar")

Voy a estudiar python

Esto es muy genial, ya que podemos tener mas simplificado y elegante nuestro codigo, y es bastante utilizado.

Sentencia For #

La sentencia de control de flujo for es otra de las estructuras fundamentales en python, que nos permite implementar sentencias en Python que se repitan un número finito de veces. Por esta razón a este tipo de sentencias se les denomina bucles.

Existen circunstancias en las que nosotros queramos repetir las sentencias de nuestro codigo de manera repetitiva, a eso le denominamos bucle.

La sentencia de control de flujo for es otra de las estructuras fundamentales de cualquier lenguaje de programación, incluido Python.

Esta estructura nos permite implementar sentencias en Python que se repitan un número finito de veces. Por esta razón a este tipo de sentencias se les denomina bucles.

La sintaxis utilizada para definir la sentencia for es la siguiente:

for <variable> in <iterable>:
    <sentencia(s)>

<iterable> Se refiere a una colección de elementos, por ejemplo, una lista o una tupla.

<variable> Recibirá uno de los elementos del objeto <iterable> en cada una de las itreaciones.

<sentencia(s)> Bloque de sentencias en Python que se ejecutará repetidamente.

Para entenderlo mejor veamos un ejemplo a continuación:

Comenzaremos creandonos una lista.

cursos = ["python", "sql", "javascript", "node"]

Ahora lo siguiente que haremos sera imprimir cada uno de los valores de nuestra lista por pantalla, sin necesidad de ejecutar la sentencia print varias veces.

Para ello lo que tenemos que hacer es utilizar la sentencia for y seguidamente tengo que definir una variable que ira recibiendo cada uno de los valores de la lista, puede ser el nombre que quieras, pero se recomienda ser lo mas descriptivo posible. En este caso pondre de nombre a la variable curso, despues usaremos la palabra reservada in y especcifiaremos nuestro objeto iterable que seria la lista cursos y :.

Finalemente imprimimos la variable que recibe cada elemento por cada iteración.

for curso in cursos:
    print(curso)

python
sql
javascript
node

Como vemos como resultado nos muestra el valor de cada iteración de nuestro codigo.

Objetos Iterables #

Para que nos quede claro en su totalidad el concepto de los bucles, es bueno que nos quede claro que son los objetos iterables.

Los iterables, son objetos que pueden utilizarse para realizar iteraciones.

Si un objeto es iterable, podemos pasarlo como argumento a la función por defecto iter() y nos devolverá un iterador.

Por ejemplo si le pasamos una cadena de texto, como resultado nos devuelve un iterador.

iter("Curso de Python")

<str_iterator at 0x1b7e7ca8240>

Podriamos aplicar lo mismo a una lista o con un diccionario.

iter([10, 20, 30, 40])

<list_iterator at 0x1b7e7bcf1b0>
iter({'curso': "python", 'profesor': "firtsmiracle"})

<dict_keyiterator at 0x1b5e7cbd530>

pero si nosotros le pasamos un objeto no iterable, nos dara un error.

iter(8)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-e50867f8c07e> in <module>
----> 1 iter(8)

TypeError: 'int' object is not iterable

Next #

La función next() nos va a devolver valores uno a uno cuando la apliquemos en un iterador.

Para ello guardamos el iterador de la lista en una variable cursos_itr, de otro modo si aplicamos el next en la lista misma nos dara un error.

cursos = ["python", "sql", "javascript", "node"]

cursos_itr = iter(curso)

type(cursos_itr)

list_iterator

next(lista_itr)

'python'

next(lista_itr)

'sql'

Debemos de tener en cuenta tambien que cuando no quedan elementos a devolver en nuestro iterador, se emite una exepción:

next(cursos_itr)

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-14-0461955db405> in <module>
----> 1 next(cursos_itr)

StopIteration: 

Uso de else en un bucle For #

Un bucle for también puede tener una cláusula else que se ejecutará cuando el iterador emita una excepción cuando no queden más elementos.

Vamos a verlo de manera practica:

Comenzemos creando una variable nomnbre que con la ayuda de la sentencia for va a iterar en los datos de nuestra lista que vamos a imprimir, despues de usaremos la sentencia else, que se ejecutara cuando el bucle finalize.

for nombre in ["Juan", "Roberto", "Carlos"]:

    print(nombre)

else:

    print("El bucle ya no tiene mas personas")

Juan
Roberto
Carlos
El bucle ya no tiene mas personas

Como resultado podemos ver que nuestro codigo nos mostro en pantalla, todos los valores del bucle y una vez que no habia mas valores por iterar nos ejecuto la sentencia else con el mensaje que establecimos.

Range #

Finalizando con la sección sobre la sentencia for, es necesario mostrar una función que viene por defecto en Python y que se utiliza muy frecuentemente en conjunto con los bucles, y esta es la función range().

Esta sentencia nos va a retornar un objeto que produce una secuencia de enteros, desde un numero de inicio a un numero final que especifiquemos.

Si le pasamos un numero entero, nos devuelve un objeto que empieza en 0 y termina en 10

range(10)

range(0, 10)

y si ahora aplicamos la función list a la previa función range que creamos nos da como resultado una lista con valores que van desde 0 a 9

list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Cabe recalcar que segun el numero o rango que especifiquemos, al ejecutarse desde el indice 0 restara un valor al numero o rango que establezcamos.

Por ejemplo si ahora establecemos un rango:

list(range(10, 20))

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Como resultado obtenemos que nuestra lista inicia desde el valor inicial que especificamos en nuestro rango 10 y termina hasta llegar al numero 19. Cumpliendose nuevamente lo antes mencionado que es restarle el ultimo valor final 20.

Otra cosa muy intersante es que la función range() también admite aplicar el concepto de stride.

list(range(4, 20, 2))

[4, 6, 8, 10, 12, 14, 15, 17, 18]

Como vemos ademas de establecer el rango, con el concepto de stride, tambien podemos especificar un numero de saltos, en este caso de 2. Por lo tanto nuestra lista nos imprimira los valores del rango de dos en dos.

Cabe recalcar que el potencial de esta función no es utilizarla con la función list(), ya que consume muchos recursos computacionales, mas bien debemos combinarla con estructura de control de flujo como el bucle for.

for numero in range(8):
    print(numero)
0
1
2
3
4
5
6
7

Del mismo modo podemos establecer rango en nuestra sentencia Fory esta de mas mencionar que tambien podriamos usar el concepto de stride.

for numero in range(10, 20):

    print(numero)

10
11
12
13
14
15
16
17
18
19

Sentencia While #

La sentencia de control de flujo while es otra de las estructuras fundamentales de Python.

Esta estructura nos permite implementar sentencias que se repitan un número infinito de veces a diferencia de for que era un numero finito.

La sintaxis utilizada para definir la sentencia while es la siguiente:

while <expresión>:
    <sentencia(s)>

<sentencia(s)> es el bloque de sentencias que se van a ejecutar de manera indefinida hasta que no se cumpla la expresión.

<expresión> es una expresión evaluada en un contexto booleano True o False que controla la ejecución del bucle while.

Para comprenderlo mejor veamoslo de manera practica.

Definimos una variable numero=1.

Usamos la sentencia while y definimos una expresión en la cual mientras que numero < 10se ejecutara nuestra sentencia que seria sumar en una unidad a la variable numero.

numero = 1

while numero < 10:

    numero += 1

    print(numero)

2
3
4
5
6
7
8
9
10

Obtendremos como resultado en pantalla el valor de cada iteración hasta que deje de cumplirse la condición ya que cuando eso pase nuestro bucle finalizara.

Probemos un ejemplo un poco mas complejo.

Declaramos una lista con nombres y un indice que igualamos a 0.

Establecemos la condición que mientras el indice sea menor a la longitud de nuestra lista nombres, nos imprima el indice de la lista que corresponda por cada iteración y a su vez tenemos que por incrementar el valor de nuestra varaible indice en una unidad cada vez que se itere, de otro modo siempre se cumpliria la codición y esta se haria infinita.

nombres = ["juan", "pedro", "carlos"]

indice = 0

while indice < len(nombres):

    print(nombres[indice], "esta en la lista")

    indice += 1

else: 

    print("no hay mas nombres")

juan esta en la lista
pedro esta en la lista
carlos esta en la lista
no hay mas nombres

Como resultado de lo ya aprendido, podemos ver que se ejecuto las sentencias definidas y cuando ya no se cumple la condición, se imprime lo establecido en el else.

Uso de else en un bucle While #

Al igual que con el bucle for, la sentencia while también permite el uso de una claúsula else y funciona de la misma manera.

Definimos una variable y establecemos una condición que va iterar mientras se cumpla, y una vez termine imprimira el codigo de la sentencia else.

numero = 4

while numero > 0:

    numero -= 1

    print(numero)

else:

    print("Se finalizo la iteración del bucle")

3
2
1
0
Se finalizo la iteración del bucle

Bucles Infinitos #

Una de las características importantes de los bucles while es que pueden ejecutarse de manera infinita. Si no se realiza un control adecuado de la expresión que se evalúa, el bucle puede ejecutarse de manera indefinida hasta que se consuman los recursos de nuestro sistema.

Similar a cuando haciamos el ejercicio practico previamente de los nombres, debemos tener cuidado al momento de establecer nuestra condición while y realizar un control adecuado en nuestras sentencias.

numero = 10
while numero > 0:
    print("Imprimir el numero", numero)

Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10
Imprimir el numero 10

Como podemos observar declaramos una variable numero=10, seguidamente establecemos la condición que mientras el numero sea mayor a 0 se ejecute nuestro print. Y debido a que no estamos estableciendo una control ya que la condición 10 > 0 siempre se va a cumplir, causara que se imprima el mensaje infinitamente hata lograr consumir todos los recursos de nuestro sistema.

Por ello hay que tener bastante cuidado en ese aspecto y establecer un control, que en este caso seria que una vez se cumpla la condición y se imprima el mensaje a nuestra variable numero restarle una unidad.

numero = 10
while numero > 0:
    print("Imprimir el numero", numero)
    numero -= 1

Imprimir el numero 10
Imprimir el numero 9
Imprimir el numero 8
Imprimir el numero 7
Imprimir el numero 6
Imprimir el numero 5
Imprimir el numero 4
Imprimir el numero 3
Imprimir el numero 2
Imprimir el numero 1

En consecuancia la condición no se hara infinita y solo se cumplira hasta que en nuestro caso numero = 1 ya que cuando este en la siguiente iteración valga 0, la condición no se cumplira y el programa finalizara.

While en una linea #

Al igual que con otras estructuras de Python, los bucles while también pueden implementarse utilizando una única línea de código.

numero = 10

while numero > 0: numero -= 1; print(numero)

9
8
7
6
5
4
3
2
1
0

Sentencias break, continue y pass #

Sentencia break #

La sentencia break es una palabra reservada de python que podemos utilizar para terminar de manera inmediata la ejecución de una estructura de control de flujo for o while. El flujo de ejecución del programa pasará a la siguiente línea de código que se encuentre fuera de la estructura de control flujo.

Si definimos un bucle for que itere entre todos los elementos de mi lista cursos, por cada interación nos da los elementos.

cursos = ["python", "javascript", "php"]

for curso in cursos:

    print(curso)

python
javascript
php

Ahora que pasa si utilizamos la sentencia break dentro de nuestro codigo previo.

cursos = ["python", "javascript", "php"]

for curso in cursos:

    print(curso)

    break

python

Como podemos ver, esta vez solo nos muestra como resultado python y esto como se menciono anteriormente es por que la sentencia break la usamos para terminar de manera inmediata la elecución de nuestro control de flujo for. Por lo tanto la instrucción itera la primera vez e imprime python, pero al definir break seguidamente despues de mostrar el valor en pantalla nos rompe inmediatamente la ejecución del bucle y pasa automaticamente a la siguiente linea del programa.

Como fuera del bucle nosotros no definimos otra linea de codigo, simplemente el programa finaliza.

Podemos hacer lo mismo con bucles while ya que el proceso de funcionamiento de break es el mismo.

numero = 5

while numero > 0:

    print(numero)

    numero -= 1

    break

5

De la misma manera al ejecutarse la primera iteración, break nos rompe inmediatamente el bucle.

Sentencia continue #

La sentencia continue es otra palabra reservada de Python sin embargo, a diferencia de la sentencia break, no termina la ejecución completa de los bucles for y while sino que termina únicamente la ejecución de la iteración actual.

Vemoslo como funciona de manera practica.

Si ejecutamos nuestro codigo anterior, pero esta vez usamos continue. Pues parece que no hubiera pasado nada, pero no.

cursos = ["python", "javascript", "php"]

for curso in cursos:

    print(curso)

    continue

python
javascript
php

Lo que sucede es que el bucle comienza a evaluar la condición curso un cursos, ejecuta la sentencia donde nos imprime python, despues encuentra la palabra continue, lo que causa que rompa la iteración actual y continua con la siguiente iteración cogiendo el siguiente string javascript y asignandosela a la variable curso.

Debemos tener en cuenta que aunque funcionen de manera similar brek y continue no son lo mismo, puesto que break rompe la ejecución entera del bucle y continue solo rompe la iteración actual.

Es por ello que si por ejemplo definimos el siguiente codigo.

cursos = ["python", "javascript", "php"]

for curso in cursos:

    print(curso)

    continue

    print("sentencia siguiente al continue")

python
javascript
php

Lo que sucede es que me va a sacar todos los valores, pero cuando llega al continue rompe la ejecución actual y continua a la siguiente por lo tanto el print definido despues nunca se ejecutara.

Pero seguro te preguntaras para que me sirve el continue si todo lo que podemos despues nunca se va a ejecutar?.

Pues nosotros podemos controlar cuando queremos que el continue se ejecute, podriamos hacer esto por ejemplo con la sentencia if.

Supongamos que de nuestra lista de cursos, no quiero que se me muestre solo el de javascript.

Pues comenzariamos a definir nuestro codigo, con nuestra sentencia for y dentro puedo definir una condición que cuando curso == javascript me ejecute un continue y de lo contrario que me imprima el curso.

cursos = ["python", "javascript", "php"]

for curso in cursos:

    if curso == "javascript":

        continue

    print(curso)

python
php

Y como resultado lo que hara sera evaluar la condición, primero ejecutandose curso == python, nos lo muestra en pantalla y en la segunda iteración comocurso == javascript ejecutara el continue y no lo mostrara ya que rompera la interación, despues finalmente curso == php y como no cumple la condición del if tambien nos lo mostrara en pantalla.

Sentencia pass #

La sentencia pass es una palabra reservada que nos permite definir el esqueleto de diferentes estructuras de diferentes tipos (funciones, if, while, for...) sin indicarle ninguna línea de código en el cuerpo de la estructura.

Esto en palabras mas simples se refiere a cuando estamos escribiendo nuestro codigo definiendo solo la estructura sin contenido.

Si por ejemplo definimos una función vacia y la ejecutamos python nos arrojara un error.

def funcion():

  File "<ipython-input-29-8a7f00d2525c>", line 1
    def funcion():
                  ^
IndentationError: expected an indented block

Entonces lo que podemos hacer es agregar en nuestra función vacia la sentencia pass.

def funcion():
    pass

Y al ejecutarlo de esta manera se omitira la sentencia, como si seria una sentencia sin ejecución y ya no veriamos el error.

Veamoslo en un ejemplo mas practico, supongamos que tenemos un bucle, pero todavia no definimos el codigo que se ejecutara dentro de el, si lo dejamos vacio y ejecutamos nos arrojara un error.

lenguajes = ["python", "golang", "ruby", "node", "rust"]
# Aun no defino el codigo que se ejecutara.
for lenguaje in lenguaje:

File "<ipython-input-32-2db429f2850e>", line 2
    # Aun no defino el codigo que se ejecutara
                                             ^
IndentationError: expected an indented block

Pero si dentro del bucle usamos pass, entonces lo que hara es omitirse la sentencia y por lo tanto no obtendremos un error y podamos seguir definiendo el esquema de nuestro codigo.

for lenguaje in lenguaje:
    # Aun no defino el codigo que se ejecutara
    pass

Python Orientado a Objetos #

En la proxima actualización….😄

Comments

comments powered by Disqus