Cómo comparar dos listas en Python y encontrar diferencias

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Comparando listas e diferenças entre arrays em Python

Comparar listas es una tarea común al sincronizar inventarios, validar resultados, detectar cambios, comprobar permisos o analizar datos. Python ofrece varias estrategias, pero no existe una única respuesta correcta. El método depende de si importa el orden, si deben conservarse valores duplicados y si necesitas saber qué elementos aparecen únicamente en cada lista.

Antes de elegir una técnica, conviene dominar las listas en Python, los conjuntos o sets, los bucles y la diferencia entre sort() y sorted().

Comparar igualdad exacta

El operador == comprueba valores, orden y cantidad de elementos:

lista_a = ["Ana", "Luis", "Marta"]
lista_b = ["Ana", "Luis", "Marta"]

print(lista_a == lista_b)  # True

Si cambia el orden, el resultado es falso:

lista_c = ["Marta", "Ana", "Luis"]
print(lista_a == lista_c)  # False

Esta comparación es adecuada para secuencias donde la posición tiene significado, como pasos de un proceso, prioridades o respuestas esperadas en una prueba.

Comparar ignorando el orden

Cuando los valores pueden repetirse y el orden no importa, ordena copias:

lista_a = [3, 1, 2, 2]
lista_b = [2, 3, 2, 1]

iguales = sorted(lista_a) == sorted(lista_b)
print(iguales)  # True

sorted() devuelve nuevas listas y conserva las originales. Este enfoque funciona cuando los elementos son comparables entre sí. Una lista que mezcla números y cadenas puede producir TypeError durante la ordenación.

Comparar con conjuntos

Si no importan el orden ni las repeticiones:

lista_a = ["python", "flask", "django", "python"]
lista_b = ["django", "python", "flask"]

print(set(lista_a) == set(lista_b))  # True

El conjunto elimina duplicados. No lo utilices si necesitas distinguir entre una aparición y varias.

La documentación oficial de set y frozenset explica unión, intersección, diferencia y relaciones entre conjuntos.

Elementos que aparecen solo en la primera lista

lista_a = ["A", "B", "C", "D"]
lista_b = ["B", "D", "E"]

solo_a = set(lista_a) - set(lista_b)
print(solo_a)  # {'A', 'C'}

También puedes utilizar el método difference:

solo_a = set(lista_a).difference(lista_b)

Elementos que aparecen solo en la segunda lista

solo_b = set(lista_b) - set(lista_a)
print(solo_b)  # {'E'}

Encontrar diferencias en ambos sentidos

diferencias = set(lista_a) ^ set(lista_b)
print(diferencias)  # {'A', 'C', 'E'}

El operador ^ calcula la diferencia simétrica: elementos presentes en uno de los conjuntos, pero no en ambos.

Encontrar elementos comunes

comunes = set(lista_a) & set(lista_b)
print(comunes)  # {'B', 'D'}

La intersección resulta útil para permisos compartidos, productos presentes en dos catálogos o usuarios incluidos en dos grupos.

Conservar el orden del resultado

Los sets no garantizan un orden semántico equivalente al original. Si quieres mantener el orden de la primera lista:

valores_b = set(lista_b)
solo_a_ordenado = [elemento for elemento in lista_a if elemento not in valores_b]
print(solo_a_ordenado)

Convertir la segunda lista a set mejora las búsquedas. Comprobar pertenencia en una lista repetidamente puede ser mucho más lento con grandes volúmenes.

Comparar duplicados con Counter

collections.Counter cuenta cuántas veces aparece cada valor:

from collections import Counter

lista_a = ["A", "A", "B", "C"]
lista_b = ["A", "B", "B", "C"]

contador_a = Counter(lista_a)
contador_b = Counter(lista_b)

print(contador_a == contador_b)  # False

Para conocer los elementos adicionales de cada lado:

extras_a = contador_a - contador_b
extras_b = contador_b - contador_a

print(extras_a)  # Counter({'A': 1})
print(extras_b)  # Counter({'B': 1})

La documentación oficial de Counter describe operaciones matemáticas entre contadores y métodos como most_common().

Comparar listas de diccionarios

Los diccionarios no pueden añadirse directamente a un set porque son mutables y no hashables. Si cada registro tiene un identificador único, crea índices:

usuarios_a = [
    {"id": 1, "nombre": "Ana", "activo": True},
    {"id": 2, "nombre": "Luis", "activo": True},
]

usuarios_b = [
    {"id": 1, "nombre": "Ana", "activo": False},
    {"id": 3, "nombre": "Marta", "activo": True},
]

indice_a = {usuario["id"]: usuario for usuario in usuarios_a}
indice_b = {usuario["id"]: usuario for usuario in usuarios_b}

Identificadores añadidos y eliminados:

ids_a = set(indice_a)
ids_b = set(indice_b)

eliminados = ids_a - ids_b
añadidos = ids_b - ids_a
comunes = ids_a & ids_b

Registros modificados:

modificados = [
    identificador
    for identificador in comunes
    if indice_a[identificador] != indice_b[identificador]
]

Este patrón es eficaz para sincronizar datos por clave primaria.

Ignorar campos durante la comparación

Algunos campos, como fecha de actualización, cambian sin representar una diferencia relevante:

def normalizar_usuario(usuario):
    return {
        clave: valor
        for clave, valor in usuario.items()
        if clave not in {"updated_at", "ultima_sesion"}
    }

cambio = normalizar_usuario(indice_a[1]) != normalizar_usuario(indice_b[1])

Define explícitamente qué campos importan. Eliminar datos sin criterio puede ocultar cambios reales.

Comparar números decimales

Los valores float pueden tener pequeñas diferencias de representación:

import math

lista_a = [0.1 + 0.2, 1.5]
lista_b = [0.3, 1.5]

iguales = all(
    math.isclose(a, b, rel_tol=1e-9, abs_tol=1e-12)
    for a, b in zip(lista_a, lista_b)
)
print(iguales)

Antes de utilizar zip, comprueba que ambas listas tengan la misma longitud. De lo contrario, los elementos sobrantes podrían ignorarse:

iguales = len(lista_a) == len(lista_b) and all(
    math.isclose(a, b) for a, b in zip(lista_a, lista_b)
)

Comparar cadenas sin distinguir mayúsculas

lista_a = ["Python", "Flask", "Django"]
lista_b = ["python", "FLASK", "django"]

normalizada_a = [texto.casefold().strip() for texto in lista_a]
normalizada_b = [texto.casefold().strip() for texto in lista_b]

print(normalizada_a == normalizada_b)

casefold() es más apropiado que lower() para comparaciones Unicode. Define la normalización según el negocio: eliminar espacios puede ser correcto para etiquetas, pero no necesariamente para contraseñas o contenido literal.

Crear una función reutilizable

from collections import Counter


def comparar_listas(lista_a, lista_b, conservar_duplicados=True):
    if conservar_duplicados:
        a = Counter(lista_a)
        b = Counter(lista_b)
        return {
            "iguales": a == b,
            "solo_a": list((a - b).elements()),
            "solo_b": list((b - a).elements()),
        }

    a = set(lista_a)
    b = set(lista_b)
    return {
        "iguales": a == b,
        "solo_a": list(a - b),
        "solo_b": list(b - a),
        "comunes": list(a & b),
    }

Documenta claramente si el orden importa y cómo se manejan duplicados. Una función ambigua produce errores difíciles de detectar.

Comparar archivos CSV

Para archivos pequeños puedes leer filas con el módulo csv y crear diccionarios indexados por una columna:

import csv


def cargar_por_id(ruta):
    with open(ruta, newline="", encoding="utf-8") as archivo:
        return {
            fila["id"]: fila
            for fila in csv.DictReader(archivo)
        }

Después aplica el mismo patrón de IDs añadidos, eliminados y modificados. Para millones de registros, considera procesamiento por bloques, base de datos o herramientas especializadas.

Rendimiento

La búsqueda x in lista puede recorrer muchos elementos. En un set o diccionario, la búsqueda promedio es mucho más rápida. Por eso conviene crear un set una sola vez antes de una comprensión. Sin embargo, esa estructura consume memoria adicional y exige elementos hashables.

Ordenar dos listas suele costar más que construir conjuntos, pero conserva duplicados. Counter también conserva cantidades y ofrece una solución clara. Elige el método por semántica primero y rendimiento después.

Pruebas

def test_comparar_duplicados():
    resultado = comparar_listas([1, 1, 2], [1, 2, 2])
    assert resultado["iguales"] is False
    assert resultado["solo_a"] == [1]
    assert resultado["solo_b"] == [2]

Incluye listas vacías, valores repetidos, órdenes distintos, tipos incompatibles y registros modificados. Las pruebas documentan el comportamiento esperado.

Errores frecuentes

Los errores más comunes son usar set cuando los duplicados importan, ordenar listas con tipos incompatibles, comparar floats con igualdad exacta, olvidar que zip se detiene en la lista más corta y convertir diccionarios mutables directamente en conjuntos. También es frecuente confundir is con ==; para comparar valores utiliza ==.

Conclusión

Para igualdad exacta utiliza ==. Para ignorar orden conservando duplicados, compara listas ordenadas o usa Counter. Para diferencias rápidas sin repeticiones, utiliza sets. Cuando trabajes con registros, crea diccionarios indexados por una clave estable. La elección correcta depende de qué significa “igual” en tu aplicación. Definir esa regla antes de escribir el código evita resultados silenciosamente incorrectos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Automação em Python para organizar arquivos do computador
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo organizar automáticamente los archivos de tu PC con Python

    Organiza automáticamente archivos del PC con Python, pathlib y shutil, evitando sobrescrituras, descargas incompletas y movimientos sin registro.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Script Python configurado para iniciar junto com o Windows
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo ejecutar un script de Python al iniciar Windows

    Configura un script Python para iniciar con Windows usando la carpeta Inicio, archivos BAT, Task Scheduler, entornos virtuales, logs y

    Ler mais

    Tempo de leitura: 6 minutos
    11/07/2026
    Sistema de backup automático de arquivos usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar copias de seguridad con Python

    Aprende a automatizar copias de seguridad con Python usando pathlib, shutil, fechas, verificación, registros y una estrategia segura de restauración.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Execução de comandos do terminal usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Subprocess en Python: ejecutar comandos del terminal

    Aprende subprocess en Python para ejecutar comandos, capturar salida, manejar errores, establecer timeouts y evitar riesgos con shell=True.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    representação de automação com ícones de engrenagens, gráficos e pessoas no background
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar tareas cotidianas con Python

    Aprende a automatizar tareas con Python: organizar archivos, renombrar lotes, procesar CSV, crear backups, usar logs y programar scripts.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    logo do BeautifulSoup em um fundo branco
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Web scraping con Python, Requests y BeautifulSoup

    Aprende web scraping con Python, Requests y BeautifulSoup: descarga páginas, selecciona elementos, limpia datos, pagina, maneja errores y exporta resultados.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026