Trabalhando com inteiros na prática
O conjunto de numero inteiros, representado por Z, inclui todos os números positivos, negativos e o zero. Parece simples até você tentar implementá-lo em código e se deparar com edge cases que ninguém te avisa. Vou mostrar como funciona de verdade, sem firula.O que é conjunto de numero inteiros e como usar
Z = {..., -3, -2, -1, 0, 1, 2, 3, ...}. Esse é o conjunto completo. Tem subconjuntos importantes: Z* (sem o zero), Z+ (positivos), Z- (negativos). Na maioria das linguagens de programação, o tipo int ou integer já cobre isso, mas tem limitações que vão te pegar desprevenido. No Python, um int pode ter qualquer tamanho — ele cresce dinamicamente. No C ou C++, um int normal tem limite de 2^31 - 1. Exceder isso gera overflow silencioso em muitas compiladores, a menos que você ative flags de warnings estritos. Já deparei com um bug em um sistema financeiro onde cálculos com inteiros grandes geravam valores negativos porque o programador esqueceu que o tipo era assinado. Metade do dia gastei rastreando um erro que era só isso.
O truque que funcionou para mim foi usar int64_t do C99 em vez de int padrão, e validar sempre o intervalo antes de operações críticas. Em Python, simplesmente use o tipo int mesmo, porque ele não transborda. Para lógica de conjuntos, a abordagem mais comum é usar estruturas de hash set, que oferecem busca O(1) na média. Lista encadeada funciona mas é O(n) na busca — inviável para grandes volumes.
Operações básicas que você precisa dominar
União, interseção, diferença e simétrica são as quatro operações fundamentais. Em Python com sets: a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
uniao = a | b
intersecao = a & b
diferenca = a - b
simetrica = a ^ b
Essas operações retornam novos sets, não modificam os originais. Se você precisa iterar sobre milhões de inteiros, considere usar numpy para operações vetorializadas. Ganha uma ordem de grandeza em velocidade comparado a loops Python puros. Aqui vai algo que poucos mencionam: a diferença simétrica de dois grandes conjuntos de inteiros consecutivos pode ser calculada muito mais rápido se você explorar o fato de que os elementos estão ordenados. Em vez de transformar tudo em set e rodar ^, use two-pointer traversal em listas ordenadas. Reduz de O(n log n) para O(n) e economiza memória consideravelmente.
Outro ponto cego: conjuntos de inteiros muito esparsos — tipo {1, 1000000, 100000000} — gastam memória enorme em hash set porque a tabela precisa crescer para acomodar os buckets. Nesses casos, uma lista ordenada ou até um array bitmap compactado é muito mais eficiente. Conheço um caso onde trocar set por sorted list reduziu o uso de memória de 4GB para 12MB num pipeline de processamento de logs.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Pegadinhas comuns e como evitar
A primeira é confundir conjuntos com listas. Set em Python não mantém ordem e não permite duplicatas. Se você passa uma lista com repetições para set(), elas somem. Já vi gente reclamar que "dados estão sumindo" e descobrir que era isso. A segunda é esquecer que inteiros negativos são perfeitamente válidos em hash sets. Alguns programadores tentam mapear Z para índices de array usando abs() ou adicionando um offset, mas isso é desnecessário na maioria das linguagens modernas. O hash de um int negativo funciona corretamente sem gambiarra.
A terceira, e mais insidiosa, é a confusão entre pertencimento e subconjunto. 3 in {1, 2, 3} é True, mas {3}
= {1, 2, 3} também é True. Usar o operador errado aqui causa bugs sutis que passam em testes unitários pequenos e explodem em produção. Se o seu conjunto de inteiros precisa suportar operações de intervalo — como "todos os inteiros entre 10 e 1000" — não armazene um por um. Use intervalos representados por tuplas (inicio, fim). Operações como união de intervalos sobrepostos se tornam trivial e a representação fica extremamente compacta. Ferramentas como o biblioteca interval-tree no Python fazem exatamente isso.
Quando inteiros não são a resposta certa
Se você está lidando com divisões exatas que geram frações, inteiros falham. Usar inteiros para cálculos monetários é uma receita para erro de arredondamento acumulado. O problema foi amplamente documentado desde os anos 80. Use Decimal ou trabalhe com centavos como inteiros, nunca com valores monetários diretamente em ponto flutuante. Também não adianta usar inteiros para representar identificadores únicos em escala massiva se você precisa de colisão zero. UUIDs ou hashes criptográficos são mais adequados. Inteiros sequenciais funcionam bem só quando você controla a fonte de geração e o espaço é limitado.
Se o conjunto de inteiros que você precisa manejar tem mais de 100 milhões de elementos e você roda consultas de interseção frequentemente, considere investir em uma base como Redis com bitmaps ou até PostgreSQL com o extension pg_intarray. A diferença de performance é abismal comparado a fazer tudo em memória com sets Python.