Preciso verificar se uma lista é um subconjunto de outra - um retorno booleano é tudo que procuro.
Testar a igualdade na lista menor após uma interseção é a maneira mais rápida de fazer isso? O desempenho é de extrema importância, considerando o número de conjuntos de dados que precisam ser comparados.
Adicionando fatos adicionais com base em discussões:
Qualquer uma das listas será a mesma para muitos testes? Faz como um deles é uma tabela de pesquisa estática.
Precisa ser uma lista? Isso não acontece - a tabela de pesquisa estática pode ser qualquer coisa que tenha melhor desempenho. O dinâmico é um ditado a partir do qual extraímos as chaves para executar uma pesquisa estática.
Qual seria a solução ideal diante do cenário?
Respostas:
A função de desempenho que o Python fornece para isso é
set.issubset
. No entanto, existem algumas restrições que tornam claro se é a resposta para sua pergunta.Uma lista pode conter itens várias vezes e tem um pedido específico. Um conjunto não. Além disso, os conjuntos funcionam apenas em objetos hashable .
Você está perguntando sobre subconjunto ou subsequência (o que significa que você desejará um algoritmo de pesquisa de cadeias)? Qualquer uma das listas será a mesma para muitos testes? Quais são os tipos de dados contidos na lista? E, nesse caso, precisa ser uma lista?
Sua outra postagem intercepta um ditado e a lista tornou os tipos mais claros e recebeu uma recomendação para usar as visualizações de chave do dicionário para a funcionalidade de conjunto. Nesse caso, sabia-se que funcionava porque as chaves de dicionário se comportam como um conjunto (tanto que, antes de termos conjuntos em Python, usamos dicionários). É de se perguntar como o problema ficou menos específico em três horas.
fonte
fonte
set(a).issubset(b)
porque, nesse caso, você só convertea
em conjunto, mas nãob
, o que economiza tempo. Você pode usartimeit
para comparar o tempo consumido em dois comandos. Por exemplo,timeit.repeat('set(a)<set(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
etimeit.repeat('set(a).issubset(b)', 'a = [1,3,5]; b = [1,3,5,7]', number=1000)
issubset
fazer é verificar se o argumento é umset
/frozenset
e, se não for, ele o converte em temporárioset
para comparação, executa a verificação e joga fora o temporárioset
. Diferenças de tempo (se houver) seriam um fator de pequenas diferenças nos custos de pesquisa do LEGB (encontrarset
uma segunda vez é mais caro do que a pesquisa de atributo em um existenteset
), mas é geralmente uma lavagem para entradas grandes o suficiente.Explicação: Gerador criando booleanos percorrendo a lista
one
verificando se esse item está na listatwo
.all()
retornaTrue
se cada item é verdadeiro, caso contrárioFalse
.Há também uma vantagem que
all
retorna False na primeira instância de um elemento ausente, em vez de precisar processar cada item.fonte
set(one).issubset(set(two))
é uma ótima solução. Com a solução que publiquei, você poderá usá-lo com qualquer objeto, se eles tiverem os operadores de comparação adequados definidos.all
curto-circuito adequado, o segundo executará todas as verificações, mesmo que seja claro desde a primeira verificação que o teste falhará. Basta soltar os colchetes para obterall(x in two for x in one)
.Supondo que os itens sejam laváveis
Se você não se importa com itens duplicados, por exemplo.
[1, 2, 2]
e[1, 2]
então basta usar:.issubset
será a maneira mais rápida de fazer isso. A verificação do comprimento antes do testeissubset
não melhora a velocidade, porque você ainda possui itens O (N + M) para percorrer e verificar.fonte
Mais uma solução seria usar a
intersection
.A interseção dos conjuntos conteria de
set one
(OU)
fonte
Se a lista1 estiver na lista 2:
(x in two for x in one)
gera uma lista deTrue
.quando fazemos a
set(x in two for x in one)
tem apenas um elemento (True).fonte
A teoria dos conjuntos é inadequada para listas, pois duplicatas resultarão em respostas erradas usando a teoria dos conjuntos.
Por exemplo:
não tem significado. Sim, fornece uma resposta falsa, mas isso não está correto, uma vez que a teoria dos conjuntos está apenas comparando: 1,3,5 versus 1,3,4,5. Você deve incluir todas as duplicatas.
Em vez disso, você deve contar cada ocorrência de cada item e fazer um valor maior que igual para verificar. Isso não é muito caro, porque não está usando operações O (N ^ 2) e não requer classificação rápida.
Ao executar isso, você obtém:
fonte
Como ninguém considerou comparar duas strings, aqui está minha proposta.
Obviamente, você pode querer verificar se o canal ("|") não faz parte de nenhuma das listas e talvez escolheu automaticamente outro caractere, mas você entendeu.
Usar uma string vazia como separador não é uma solução, pois os números podem ter vários dígitos ([12,3]! = [1,23])
fonte
Perdoe-me se eu estiver atrasado para a festa. ;)
Para verificar se um
set A
é um subconjunto deset B
,Python
possuiA.issubset(B)
eA <= B
. Ele funcionaset
apenas e funciona muito bem, mas a complexidade da implementação interna é desconhecida. Referência: https://docs.python.org/2/library/sets.html#set-objectsEu vim com um algoritmo para verificar se
list A
é um subconjunto daslist B
seguintes observações.sort
duas listas antes de comparar os elementos para qualificar para o subconjunto.break
aloop
quando o valor do elemento da segunda listaB[j]
é maior que o valor do elemento da primeira listaA[i]
.last_index_j
é usado para iniciarloop
sobrelist B
onde último saiu fora. Ela ajuda a evitar começar comparações a partir do iníciolist B
(o que é, como você pode imaginar desnecessário, para começarlist B
a partirindex 0
em posterioriterations
.)O(n ln n)
Cada complexidade será cada uma para classificar as duas listas eO(n)
verificar o subconjunto.O(n ln n) + O(n ln n) + O(n) = O(n ln n)
.O código possui várias
print
instruções para ver o que está acontecendo em cada umaiteration
dasloop
. Estes destinam-se apenas à compreensão.Verifique se uma lista é subconjunto de outra lista
Resultado
fonte
O código abaixo verifica se um determinado conjunto é um "subconjunto adequado" de outro conjunto
fonte
No python 3.5, você pode fazer um
[*set()][index]
para obter o elemento É uma solução muito mais lenta que outros métodos.ou apenas com len e definir
fonte
Aqui está como eu sei se uma lista é um subconjunto de outra, a sequência é importante para mim no meu caso.
fonte
A maioria das soluções considera que as listas não possuem duplicatas. Caso suas listas tenham duplicatas, você pode tentar o seguinte:
Ele garante que a sublista nunca tenha elementos diferentes da lista ou uma quantidade maior de um elemento comum.
fonte
Se você está perguntando se uma lista está "contida" em outra lista, então:
Se você está perguntando se cada elemento da lista A tem um número igual de elementos correspondentes na lista B, tente:
fonte
Se
a2 is subset of a1
entãoLength of set(a1 + a2) == Length of set(a1)
fonte