Ir al contenido principal

Métodos comunes de estructuras de datos

Introducción

Las estructuras de datos en Python (listas, tuplas, diccionarios y conjuntos) nos permiten organizar y manipular la información de manera eficiente. Cada estructura tiene sus propios métodos específicos que facilitan operaciones como añadir, eliminar, buscar o transformar elementos. Dominar estos métodos es fundamental para escribir código Python elegante y eficaz. En este artículo, exploraremos los métodos más comunes y útiles de cada estructura de datos, con ejemplos prácticos que te ayudarán a sacar el máximo provecho de estas herramientas.

Métodos de listas

Las listas son una de las estructuras de datos más versátiles en Python, y disponen de numerosos métodos para manipularlas.

Métodos para añadir elementos

# Crear una lista inicial
frutas = ["manzana", "plátano"]

# append(): añade un elemento al final
frutas.append("naranja")
print(frutas)  # ['manzana', 'plátano', 'naranja']

# insert(): añade un elemento en una posición específica
frutas.insert(1, "fresa")  # Inserta 'fresa' en la posición 1
print(frutas)  # ['manzana', 'fresa', 'plátano', 'naranja']

# extend(): añade todos los elementos de otra secuencia
mas_frutas = ["uva", "melón"]
frutas.extend(mas_frutas)
print(frutas)  # ['manzana', 'fresa', 'plátano', 'naranja', 'uva', 'melón']

Métodos para eliminar elementos

# remove(): elimina la primera aparición de un valor específico
frutas.remove("plátano")
print(frutas)  # ['manzana', 'fresa', 'naranja', 'uva', 'melón']

# pop(): elimina y devuelve el elemento en una posición
# (por defecto, el último)
ultima_fruta = frutas.pop()
print(ultima_fruta)  # 'melón'
print(frutas)  # ['manzana', 'fresa', 'naranja', 'uva']

fruta_posicion = frutas.pop(1)
print(fruta_posicion)  # 'fresa'
print(frutas)  # ['manzana', 'naranja', 'uva']

# clear(): elimina todos los elementos
frutas.clear()
print(frutas)  # []

Métodos para buscar y ordenar

numeros = [4, 1, 7, 3, 9, 2]

# index(): devuelve la posición de la primera aparición de un valor
posicion = numeros.index(7)
print(posicion)  # 2

# count(): cuenta el número de apariciones de un valor
repeticiones = [1, 2, 3, 1, 4, 1].count(1)
print(repeticiones)  # 3

# sort(): ordena la lista in situ (modifica la original)
numeros.sort()
print(numeros)  # [1, 2, 3, 4, 7, 9]

# sort() con parámetros: orden descendente
numeros.sort(reverse=True)
print(numeros)  # [9, 7, 4, 3, 2, 1]

# sorted(): devuelve una nueva lista ordenada (no modifica la original)
palabras = ["casa", "árbol", "perro"]
palabras_ordenadas = sorted(palabras)
print(palabras)  # ["casa", "árbol", "perro"] (sin cambios)
print(palabras_ordenadas)  # ["árbol", "casa", "perro"]

Otros métodos útiles

lista = [1, 2, 3]

# copy(): crea una copia superficial de la lista
copia = lista.copy()
copia.append(4)
print(lista)  # [1, 2, 3] (sin cambios)
print(copia)  # [1, 2, 3, 4]

# reverse(): invierte el orden de los elementos
lista.reverse()
print(lista)  # [3, 2, 1]

Métodos de tuplas

Las tuplas tienen menos métodos que las listas debido a su naturaleza inmutable, pero comparten algunos métodos de acceso y búsqueda.

coordenadas = (10, 20, 30, 20)

# count(): cuenta el número de apariciones de un valor
apariciones = coordenadas.count(20)
print(apariciones)  # 2

# index(): devuelve la posición de la primera aparición de un valor
posicion = coordenadas.index(30)
print(posicion)  # 2

# No existen métodos para modificar la tupla como append() o remove()
# debido a que las tuplas son inmutables

Métodos de diccionarios

Los diccionarios tienen métodos específicos para trabajar con pares clave-valor.

Métodos para acceder a elementos

estudiante = {
    "nombre": "Laura",
    "edad": 22,
    "carrera": "Informática"
}

# get(): devuelve el valor de una clave (con valor por defecto opcional)
nombre = estudiante.get("nombre")
print(nombre)  # "Laura"

# Si la clave no existe, get() devuelve None o un valor por defecto
ciudad = estudiante.get("ciudad")
print(ciudad)  # None

# Con valor por defecto
ciudad = estudiante.get("ciudad", "Desconocida")
print(ciudad)  # "Desconocida"

# keys(): devuelve un objeto vista con todas las claves
claves = estudiante.keys()
print(list(claves))  # ['nombre', 'edad', 'carrera']

# values(): devuelve un objeto vista con todos los valores
valores = estudiante.values()
print(list(valores))  # ['Laura', 22, 'Informática']

# items(): devuelve un objeto vista con pares (clave, valor)
pares = estudiante.items()
print(list(pares))  # [('nombre', 'Laura'), ('edad', 22), ('carrera', 'Informática')]

Métodos para modificar diccionarios

# update(): actualiza el diccionario con los pares de otro diccionario
informacion_adicional = {"ciudad": "Madrid", "semestre": 3}
estudiante.update(informacion_adicional)
print(estudiante)
# {'nombre': 'Laura', 'edad': 22, 'carrera': 'Informática', 'ciudad': 'Madrid', 'semestre': 3}

# Si las claves existen, update() actualiza sus valores
actualizacion = {"edad": 23, "semestre": 4}
estudiante.update(actualizacion)
print(estudiante)
# {'nombre': 'Laura', 'edad': 23, 'carrera': 'Informática', 'ciudad': 'Madrid', 'semestre': 4}

# pop(): elimina una clave y devuelve su valor
carrera = estudiante.pop("carrera")
print(carrera)  # "Informática"
print(estudiante)
# {'nombre': 'Laura', 'edad': 23, 'ciudad': 'Madrid', 'semestre': 4}

# popitem(): elimina y devuelve el último par insertado (Python 3.7+)
ultimo_par = estudiante.popitem()
print(ultimo_par)  # ('semestre', 4)
print(estudiante)
# {'nombre': 'Laura', 'edad': 23, 'ciudad': 'Madrid'}

# clear(): elimina todos los elementos
estudiante.clear()
print(estudiante)  # {}

Otros métodos útiles de diccionarios

usuario = {"nombre": "Carlos", "rol": "admin"}

# copy(): crea una copia superficial del diccionario
copia = usuario.copy()
copia["rol"] = "usuario"
print(usuario)  # {'nombre': 'Carlos', 'rol': 'admin'}
print(copia)    # {'nombre': 'Carlos', 'rol': 'usuario'}

# setdefault(): devuelve el valor de una clave o inserta un par si no existe
email = usuario.setdefault("email", "sin@email.com")
print(email)  # "sin@email.com"
print(usuario)  # {'nombre': 'Carlos', 'rol': 'admin', 'email': 'sin@email.com'}

# fromkeys(): crea un diccionario con claves de un iterable y un valor común
claves = ["nombre", "apellido", "edad"]
ficha = dict.fromkeys(claves, "desconocido")
print(ficha)  # {'nombre': 'desconocido', 'apellido': 'desconocido', 'edad': 'desconocido'}

Métodos de conjuntos

Los conjuntos tienen métodos específicos para operaciones matemáticas de conjuntos.

Métodos para añadir y eliminar elementos

colores = {"rojo", "verde"}

# add(): añade un elemento al conjunto
colores.add("azul")
print(colores)  # {'rojo', 'verde', 'azul'} (el orden puede variar)

# update(): añade múltiples elementos de otro iterable
mas_colores = ["amarillo", "negro"]
colores.update(mas_colores)
print(colores)  # {'rojo', 'verde', 'azul', 'amarillo', 'negro'}

# remove(): elimina un elemento (provoca error si no existe)
colores.remove("verde")
print(colores)  # {'rojo', 'azul', 'amarillo', 'negro'}

# discard(): elimina un elemento si existe (no provoca error si no existe)
colores.discard("morado")  # No hace nada porque 'morado' no está en el conjunto

# pop(): elimina y devuelve un elemento aleatorio
color = colores.pop()
print(color)  # Un color aleatorio del conjunto
print(colores)  # El conjunto sin el color extraído

# clear(): elimina todos los elementos
colores.clear()
print(colores)  # set()

Métodos para operaciones matemáticas

conjunto_a = {1, 2, 3, 4}
conjunto_b = {3, 4, 5, 6}

# union(): devuelve un nuevo conjunto con elementos de ambos conjuntos
union = conjunto_a.union(conjunto_b)
print(union)  # {1, 2, 3, 4, 5, 6}

# intersection(): devuelve un nuevo conjunto con elementos comunes
interseccion = conjunto_a.intersection(conjunto_b)
print(interseccion)  # {3, 4}

# difference(): devuelve un nuevo conjunto con elementos solo en el primero
diferencia = conjunto_a.difference(conjunto_b)
print(diferencia)  # {1, 2}

# symmetric_difference(): elementos en uno u otro conjunto, pero no en ambos
dif_simetrica = conjunto_a.symmetric_difference(conjunto_b)
print(dif_simetrica)  # {1, 2, 5, 6}

Métodos para comparar conjuntos

numeros = {1, 2, 3, 4, 5}
pares = {2, 4}
impares = {1, 3, 5}

# issubset(): comprueba si todos los elementos están en otro conjunto
print(pares.issubset(numeros))  # True

# issuperset(): comprueba si contiene todos los elementos de otro conjunto
print(numeros.issuperset(pares))  # True

# isdisjoint(): comprueba si dos conjuntos no tienen elementos comunes
print(pares.isdisjoint(impares))  # True

Métodos para modificar conjuntos in situ

grupo_a = {1, 2, 3}
grupo_b = {3, 4, 5}

# update() / |=: actualiza con la unión
copia_a = grupo_a.copy()
copia_a.update(grupo_b)  # Equivalente a copia_a |= grupo_b
print(copia_a)  # {1, 2, 3, 4, 5}

# intersection_update() / &=: actualiza con la intersección
copia_a = grupo_a.copy()
copia_a.intersection_update(grupo_b)  # Equivalente a copia_a &= grupo_b
print(copia_a)  # {3}

# difference_update() / -=: actualiza con la diferencia
copia_a = grupo_a.copy()
copia_a.difference_update(grupo_b)  # Equivalente a copia_a -= grupo_b
print(copia_a)  # {1, 2}

# symmetric_difference_update() / ^=: actualiza con la diferencia simétrica
copia_a = grupo_a.copy()
copia_a.symmetric_difference_update(grupo_b)  # Equivalente a copia_a ^= grupo_b
print(copia_a)  # {1, 2, 4, 5}

Métodos comunes a varias estructuras

Algunos métodos y funciones pueden aplicarse a múltiples estructuras de datos:

# len(): devuelve el número de elementos
print(len([1, 2, 3]))           # 3 (lista)
print(len((1, 2, 3)))           # 3 (tupla)
print(len({"a": 1, "b": 2}))    # 2 (diccionario)
print(len({1, 2, 3}))           # 3 (conjunto)

# max() y min(): devuelven el valor máximo y mínimo
print(max([5, 10, 3]))          # 10
print(min([5, 10, 3]))          # 3
print(max("python"))            # 'y' (alfabéticamente mayor)

# sum(): suma todos los elementos numéricos
print(sum([1, 2, 3, 4]))        # 10
print(sum({10, 20, 30}))        # 60

# any(): devuelve True si al menos un elemento es True
print(any([False, False, True])) # True
print(any([0, "", False]))      # False

# all(): devuelve True si todos los elementos son True
print(all([True, True, True]))  # True
print(all([True, False, True])) # False

Iteración sobre estructuras de datos

Podemos recorrer todas estas estructuras utilizando bucles:

# Iteración sobre una lista
numeros = [10, 20, 30]
for numero in numeros:
    print(numero, end=" ")  # 10 20 30

print()  # Salto de línea

# Iteración sobre una tupla
colores = ("rojo", "verde", "azul")
for color in colores:
    print(color, end=" ")  # rojo verde azul

print()

# Iteración sobre un diccionario (claves por defecto)
persona = {"nombre": "Ana", "edad": 30}
for clave in persona:
    print(f"{clave}: {persona[clave]}", end=" ")  # nombre: Ana edad: 30

print()

# Iteración sobre pares clave-valor
for clave, valor in persona.items():
    print(f"{clave}={valor}", end=" ")  # nombre=Ana edad=30

print()

# Iteración sobre un conjunto
letras = {"a", "b", "c"}
for letra in letras:
    print(letra, end=" ")  # El orden puede variar, por ejemplo: c a b

Consejos para elegir el método adecuado

  1. Para transformaciones no destructivas: Prefiere métodos que devuelvan una nueva estructura en lugar de modificar la original.

    # Mejor usar sorted() en lugar de sort() si no quieres modificar la original
    numeros_ordenados = sorted([3, 1, 2])
    
  2. Para acceso seguro en diccionarios: Usa get() en lugar de la notación de corchetes para evitar errores.

    # Mejor esto: 
    valor = diccionario.get("clave", "valor_por_defecto")
    # Que esto (puede provocar KeyError):
    # valor = diccionario["clave"]
    
  3. Para operaciones de conjuntos: Recuerda que los métodos de conjuntos suelen tener una versión que devuelve un nuevo conjunto y otra que actualiza in situ.

    # Devuelve un nuevo conjunto
    nuevo = conjunto_a.union(conjunto_b)
    # Actualiza conjunto_a in situ
    conjunto_a.update(conjunto_b)
    
  4. Para listas y conjuntos grandes: Elige métodos optimizados para el rendimiento.

    # Para comprobar si un elemento existe:
    # En listas (lenta para listas grandes):
    existe = elemento in lista_grande
    # En conjuntos (mucho más rápida):
    existe = elemento in set(lista_grande)
    

Resumen

Los métodos de estructuras de datos en Python nos proporcionan herramientas potentes para manipular y transformar datos de manera eficiente. Cada estructura tiene sus propios métodos especializados que se adaptan a sus características únicas: las listas ofrecen métodos para modificar secuencias ordenadas, las tuplas proporcionan métodos limitados debido a su inmutabilidad, los diccionarios facilitan el trabajo con pares clave-valor, y los conjuntos incluyen operaciones matemáticas de teoría de conjuntos.

Dominar estos métodos te permitirá escribir código más limpio, eficiente y expresivo. En el próximo artículo, veremos cómo convertir entre diferentes tipos de datos en Python, lo que te dará aún más flexibilidad al trabajar con estas estructuras.