Compara listas en Python: diferencias y duplicados

Actualizado el: 21/08/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

    Imagem ilustrativa de conteúdo Python para YouTube
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    YouTube con Python: descarga vídeos propios con yt-dlp

    Descarga copias de tus propios vídeos o contenido autorizado con Python y yt-dlp, validación, historial, límites, FFmpeg y prácticas responsables.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Automação de postagens no Twitter usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Tweepy: automatiza publicaciones en X con Python

    Automatiza publicaciones en X con Tweepy, credenciales seguras, validación, deduplicación, programación, logs y prácticas responsables contra el spam.

    Ler mais

    Tempo de leitura: 5 minutos
    12/07/2026
    Geração e edição de planilhas Excel usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Excel con Python: crea y edita con openpyxl

    Crea y edita Excel con Pandas y openpyxl: hojas, fórmulas, estilos, filtros, validación, gráficos, rutas seguras y manejo de archivos

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Gerando aplicativo APK Android com Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    APK Android con Python, Kivy y Buildozer

    Genera un APK Android con Python, Kivy y Buildozer: configuración, permisos, recursos, compilación, pruebas, almacenamiento, firma y publicación.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Web scraper de notícias em Python com envio para Telegram
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Scraper de noticias con Python y Telegram

    Crea un scraper de noticias con Requests y Beautiful Soup, elimina duplicados y envía titulares a Telegram de forma segura

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Compactação de arquivos ZIP usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    zipfile: descomprime archivos ZIP con seguridad

    Descomprime archivos ZIP con Python de forma segura: valida rutas, evita Zip Slip, limita tamaños, verifica integridad y procesa archivos

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026