36 - Funciones: parámetros mutables e inmutables

En Python tenemos tipos de datos inmutables:

enteros
float
string
tuplas

Mutables:

listas
diccionarios

Esto tiene mucha importancia cuando enviamos a una función una variable mutable, veremos con un ejemplo como podemos pasar como parámetro una lista a una función y posteriormente cambiar su contenido y esto se vea reflejado en la variable que le enviamos al llamarla.

Problema 1:

Confeccionar un programa que contenga las siguientes funciones:
1) Carga de una lista y retorno al bloque principal.
2) Fijar en cero todos los elementos de la lista que tengan un valor menor a 10.
3) Imprimir la lista

Programa: ejercicio166.py

Ver video

def cargar():
    lista=[]
    continua="s"
    while continua=="s":
        valor=int(input("Ingrese un valor:"))
        lista.append(valor)
        continua=input("Agrega otro elemento a la lista[s/n]:")
    return lista


def fijar_cero(li):
    for x in range(len(li)):
        if li[x]<10:
            li[x]=0


def imprimir(lista):
    for elemento in lista:
        print(elemento,"-",sep="",end="")
    print("")

# bloque principal

lista=cargar()
print("Lista antes de modificar")
imprimir(lista)
fijar_cero(lista)
print("Lista despues de modificar")
imprimir(lista)

La primer función permite la carga de una lista de enteros hasta que el operador no desee cargar más valores:

def cargar():
    lista=[]
    continua="s"
    while continua=="s":
        valor=int(input("Ingrese un valor:"))
        lista.append(valor)
        continua=input("Agrega otro elemento a la lista[s/n]:")
    return lista

Lo nuevo aparece en la función fijar_cero que recibe como parámetro una lista llamada "li" y dentro de la función modificamos los elementos de la lista, estos cambios luego se ven reflejados en la variable definida en el bloque principal de nuestro programa:

def fijar_cero(li):
    for x in range(len(li)):
        if li[x]<10:
            li[x]=0

Si ejecutamos este programa e ingresamos algunos elementos de la lista con valores inferiores a 10 veremos luego que la variable global "lista" es modificada:

listas modificadas en una función

Problema 2:

Confeccionar un programa que contenga las siguientes funciones:
1) Carga de una lista de 5 nombres.
2) Ordenar alfabéticamente la lista.
3) Imprimir la lista de nombres

Programa: ejercicio167.py

Ver video

def cargar():
    nombres=[]
    for x in range(5):
        nom=input("Ingrese nombre:")
        nombres.append(nom)
    return nombres


def ordenar(nombres):
    for k in range(4):
        for x in range(4):
            if nombres[x]>nombres[x+1]:
                aux=nombres[x]
                nombres[x]=nombres[x+1]
                nombres[x+1]=aux


def imprimir(nombres):
    for x in range(len(nombres)):
        print(nombres[x]," ",end="")


# bloque principal

nombres=cargar()
ordenar(nombres)
imprimir(nombres)

En este problema tenemos que intercambiar los elementos de una lista y dejarlos ordenados. La primer función para crear la lista y cargarla no presenta nada nuevo a lo visto en problemas anteriores:

def cargar():
    nombres=[]
    for x in range(5):
        nom=input("Ingrese nombre:")
        nombres.append(nom)
    return nombres

El algoritmo de ordenamiento lo vimos cuando solo conocíamos la programación lineal, por lo que todas las variables eran globales. Ahora tenemos que hacer el ordenamiento de la lista en una función y que se modifique la variable que le pasamos desde el bloque principal:

def ordenar(nombres):
    for k in range(4):
        for x in range(4):
            if nombres[x]>nombres[x+1]:
                aux=nombres[x]
                nombres[x]=nombres[x+1]
                nombres[x+1]=aux

El parámetro "nombres" al ser modificado (nombres[x]=nombres[x+1] y nombres[x+1]=aux) se modifica la variable global que le pasamos desde el bloque principal:

# bloque principal

nombres=cargar()
ordenar(nombres)
imprimir(nombres)

Luego de ejecutarse la función "ordenar" llamamos a la función "imprimir" pasando la variable "nombres" ya ordenada.

Veremos un último problema pasando y modificando una estructura de datos tipo diccionario. Recordemos que listas y diccionarios son mutables en Python. Cuando pasamos a una función como parámetro una lista o un diccionario luego los cambios que sufre la estructura de datos se ven luego reflejadas en las variables que se pasaron desde el bloque principal.

Problema 3:

Confeccionar un programa que almacene en un diccionario como clave el nombre de un contacto y como valor su número telefónico:
1) Carga de contactos y su número telefónico.
2) Pemitir modificar el número telefónico. Se ingresa el nombre del contacto para su búsqueda.
3) Imprimir la lista completa de contactos con sus números telefónicos.

Programa: ejercicio168.py

Ver video

def cargar():
    contactos={}
    continua="s"
    while continua=="s":
        nombre=input("Ingrese el nombre del contacto:")
        telefono=input("Ingrese el numero de telefono:")
        contactos[nombre]=telefono
        continua=input("Ingresa otro contacto[s/n]?:")
    return contactos


def modificar_telefono(contactos):
    nombre=input("Ingrese el nombre de contacto a modificar el telefono:")
    if nombre in contactos:
        telefono=input("Ingrese el nuevo numero telefonico")
        contactos[nombre]=telefono
    else:
        print("No existe un contacto con el nombre ingresado")


def imprimir(contactos):
    print("Listado de todos los contactos")
    for nombre in contactos:
        print(nombre,contactos[nombre])


# bloque principal

contactos=cargar()
modificar_telefono(contactos)
imprimir(contactos)

La primer función nos permite cargar los nombres de contactos con sus respectivos teléfonos en un diccionario llamado "contactos", la función retorna este diccionario y se almacena posteriormente en una variable global:

def cargar():
    contactos={}
    continua="s"
    while continua=="s":
        nombre=input("Ingrese el nombre del contacto:")
        telefono=input("Ingrese el numero de telefono:")
        contactos[nombre]=telefono
        continua=input("Ingresa otro contacto[s/n]?:")
    return contactos

En el bloque principal se guarda en:

# bloque principal

contactos=cargar()

La función "modificar_telefono" recibe como parámetro el diccionario "contactos", solicita la carga de un contacto, en el caso que exita se procede a solicitar el nuevo teléfono y modificar el diccionario:

def modificar_telefono(contactos):
    nombre=input("Ingrese el nombre de contacto a modificar el telefono:")
    if nombre in contactos:
        telefono=input("Ingrese el nuevo numero telefonico")
        contactos[nombre]=telefono
    else:
        print("No existe un contacto con el nombre ingresado")

Con la modificación del parámetro en la función "modificar_telefono" se está modificando la variable global que le pasamos desde el bloque principal:

# bloque principal

contactos=cargar()
modificar_telefono(contactos)

Ahora cuando imprimimos el diccionario podemos ver que el teléfono aparece modificado:

def imprimir(contactos):
    print("Listado de todos los contactos")
    for nombre in contactos:
        print(nombre,contactos[nombre])

Problema propuesto

  • Crear un diccionario en Python para almacenar los datos de empleados de una empresa. La clave será su número de legajo y en su valor almacenar una lista con el nombre, profesión y sueldo.

    Desarrollar las siguientes funciones:
    1) Carga de datos de empleados.
    2) Permitir modificar el sueldo de un empleado. Ingresamos su número de legajo para buscarlo.
    3) Mostrar todos los datos de empleados que tienen una profesión de "analista de sistemas"

    Ver video

Solución
ejercicio169.py

def cargar():
    empleados={}
    continua="s"
    while continua=="s":
        legajo=int(input("Ingrese el numero de legajo:"))
        nombre=input("Ingrese el nombre del empleado:")
        profesion=input("Ingrese el nombre de la profesion:")
        sueldo=float(input("Ingrese el sueldo:"))
        empleados[legajo]=[nombre,profesion,sueldo]
        continua=input("Ingresa los datos de otro empleado[s/n]:")
    return empleados


def imprimir(empleados):
    print("Listado completo de empleados")
    for legajo in empleados:
        print(legajo,empleados[legajo][0],empleados[legajo][1],empleados[legajo][2])


def modificar_sueldo(empleados):
    legajo=int(input("Ingrese el numero de legajo para buscar empleado:"))
    if legajo in empleados:
        sueldo=float(input("Ingrese nuevo sueldo:"))
        empleados[legajo][2]=sueldo
    else:
        print("No existe un empleado con dicho numero de legajo")


def imprimir_analistas(empleados):
    print("Listado de empleados con profesion \"analista de sistemas\"")
    for legajo in empleados:
        if empleados[legajo][1]=="analista de sistemas":
            print(legajo,empleados[legajo][0],empleados[legajo][2])


# bloque principal

empleados=cargar()
imprimir(empleados)
modificar_sueldo(empleados)
imprimir(empleados)
imprimir_analistas(empleados)