treatment - upper python




Python-verificar se uma lista é um subconjunto da outra (10)

A função de desempenho que o Python fornece para isso é set.issubset . Ele tem algumas restrições que não deixam claro se é a resposta à sua pergunta, no entanto.

Uma lista pode conter itens várias vezes e tem um pedido específico. Um conjunto não. Para obter conjuntos de alto desempenho, trabalhe somente em objetos hashable .

Você está perguntando sobre subconjunto ou subsequência (o que significa que você vai querer um algoritmo de busca de string)? Alguma das listas será a mesma para muitos testes? Quais são os tipos de dados contidos na lista? E para isso, precisa ser uma lista?

Sua outra postagem cruzou um dicionário e uma lista tornou os tipos mais claros e obteve uma recomendação de usar as principais exibições de dicionário para sua funcionalidade funcional. Nesse caso, sabia-se que funcionava porque as chaves do dicionário se comportavam como um conjunto (tanto que, antes de configurarmos o Python, usamos dicionários). Alguém se pergunta como a questão ficou menos específica em três horas.

Eu preciso verificar se uma lista é um subconjunto de outro - um retorno booleano é tudo que eu procuro.
Está testando igualdade na lista menor após uma interseção a maneira mais rápida de fazer isso?
O desempenho é de extrema importância, dada a quantidade de conjuntos de dados que precisam ser comparados.
Adicionando mais fatos com base em discussões:

  1. Alguma das listas será a mesma para muitos testes?
    Faz como um deles é uma tabela de pesquisa estática
  2. Precisa ser uma lista?
    Não - a tabela de pesquisa estática pode ser qualquer coisa que tenha melhor desempenho.
    A dinâmica é um dict do qual extraímos as chaves para realizar uma pesquisa estática.

Qual seria a solução ideal dada a situação?


A teoria dos conjuntos é inadequada para listas, pois as duplicatas resultarão em respostas erradas usando a teoria dos conjuntos.

Por exemplo:

a = [1, 3, 3, 3, 5]
b = [1, 3, 3, 4, 5]
set(b) > set(a)

não tem significado. Sim, dá uma resposta falsa, mas isso não está correto, já 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 o equivalente a verificar. Isso não é muito caro, porque não está usando operações O (N ^ 2) e não requer classificação rápida.

#!/usr/bin/env python

from collections import Counter

def containedInFirst(a, b):
  a_count = Counter(a)
  b_count = Counter(b)
  for key in b_count:
    if a_count.has_key(key) == False:
      return False
    if b_count[key] > a_count[key]:
      return False
  return True


a = [1, 3, 3, 3, 5]
b = [1, 3, 3, 4, 5]
print "b in a: ", containedInFirst(a, b)

a = [1, 3, 3, 3, 4, 4, 5]
b = [1, 3, 3, 4, 5]
print "b in a: ", containedInFirst(a, b)

Então, executando isso, você obtém:

$ python contained.py 
b in a:  False
b in a:  True

Assumindo que os itens são hashable

>>> from collections import Counter
>>> not Counter([1, 2]) - Counter([1])
False
>>> not Counter([1, 2]) - Counter([1, 2])
True
>>> not Counter([1, 2, 2]) - Counter([1, 2])
False

Se você não se importa com itens duplicados, por exemplo. [1, 2, 2] e [1, 2] depois é só usar:

>>> set([1, 2, 2]).issubset([1, 2])
True

Está testando igualdade na lista menor após uma interseção a maneira mais rápida de fazer isso?

.issubset será a maneira mais rápida de fazer isso. Verificar o tamanho antes de testar o issubset não aumentará a velocidade porque você ainda tem itens O (N + M) para percorrer e verificar.


Eu sei que está atrasado, mas só queria atualizar a resposta com o que funcionou para mim (Python 3)

# var 1
x = [1,2,3,4]
#  var 2
y = [1,2]

# check if var2 is subset of var1
all([z in x for z in y])

Felicidades.


No python 3.5 você pode fazer um [*set()][index] para obter o elemento. É uma solução muito mais lenta que outros métodos.

one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

result = set(x in two for x in one)

[*result][0] == True

ou apenas com len e set

len(set(a+b)) == len(set(a))

O código abaixo verifica se um determinado conjunto é um "subconjunto adequado" de outro conjunto

 def is_proper_subset(set, superset):
     return all(x in superset for x in set) and len(set)<len(superset)

Se você está perguntando se uma lista está "contida" em outra lista, então:

>>>if listA in listB: return True

Se você está perguntando se cada elemento na lista A tem um número igual de elementos correspondentes em listB tente:

all(True if listA.count(item) <= listB.count(item) else False for item in listA)

Tente bit a bit E

>>> set([1,2]) & set([1,2,3])
set([1, 2])
>>> set([0]) & set([1,2,3])
set([])

Ainda não o perfilei.


one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

all(x in two for x in one)

Explanation: Gerador criando booleanos fazendo um loop pela lista one verificando se esse item está na lista two . all() retorna True se todo item for True , senão False .

Há também uma vantagem que all retornam False na primeira instância de um elemento ausente, em vez de ter que processar cada item.


one = [1, 2, 3]
two = [9, 8, 5, 3, 2, 1]

set(x in two for x in one) == set([True])

Se list1 estiver na lista 2:

  • (x in two for x in one) gera uma lista de True .

  • quando fazemos um set(x in two for x in one) tem apenas um elemento (True).





list