Stack Overflow em Português Asked by Nebenzahl on November 13, 2021
Eu tenho duas listas com valores, e quando tento pesquisar um item de uma em outra, para ver se existe, está retornando False
mesmo se sabendo que o item existe na lista pesquisada.
proc = [1,2,3,4]
fat = [3,4,5,6]
for p in proc:
if proc[0] not in fat:
result.append(proc[0])
print(result)
[]
Estas listas estao vindo de SELECT
em um banco de dados, e contém um campo de tabelas.
O que posso estar fazendo de errado?
Se a ideia (confirmada nos comentários) é ter os elementos de proc
que não estão em fat
, então uma opção é:
proc = [1, 2, 3, 4]
fat = [3, 4, 5, 6]
result = []
for p in proc:
if p not in fat:
result.append(p)
print(result) # [1, 2]
Ou seja, para cada elemento de proc
, verifique se ele não está em fat
(e se não estiver, adicione em result
).
O erro do seu código é que você estava verificando proc[0]
(o primeiro elemento de proc
) em todas as iterações.
Outra alternativa para o código acima é usar uma list comprehension, bem mais sucinta e pythônica:
result = [ p for p in proc if p not in fat ]
Mas tem um detalhe aí. Para cada elemento de proc
, temos que verificar se o mesmo está em fat
. E o operador in
tem complexidade linear: ele percorre fat
desde o início, até encontrar o elemento (ou percorre a lista toda, no caso do elemento não existir nela). Ou seja, este algoritmo percorre várias e várias vezes a mesma lista (o que o torna um forte candidato a ser um Shlemiel the painter’s algorithm).
Se a ordem dos elementos não é importante, e não há elementos duplicados (ou há, mas no resultado as duplicadas podem ser eliminadas), uma opção é usar set
, que é uma estrutura otimizada para certas operações, como verificar se um elemento existe, entre outras.
Assim, a ideia é transformar cada lista em um set
, subtraí-los (assim eu terei outro set
contendo os elementos de um que não estão no outro), e no final transformo novamente em lista:
result = list(set(proc) - set(fat))
Lembrando novamente que:
set
não garante a ordem dos elementos, então a lista result
não necessariamente terá os números na mesma ordem em que estavam na lista original (pode ser que sim, pode ser que não, então não conte com isso)set
elimina valores duplicados, então se a lista proc
for, por exemplo, [1, 2, 3, 4, 1]
, o resultado final será apenas [1, 2]
Mas se manter a ordem original dos elementos e/ou não eliminar valores duplicados forem requisitos do problema, aí não tem jeito, tem que fazer o for
mesmo.
Apenas para comparar o desempenho de cada solução, fiz um pequeno teste com o módulo timeit
:
import random
import timeit
# criar listas com mil números aleatórios
nums = range(10000) # números possíveis para as listas
proc = random.choices(nums, k=1000)
fat = random.choices(nums, k=1000)
n = 100 # rodar 100 vezes cada teste
r = 3 # repetir por 3 vezes (assim, repeat retorna uma lista com 3 tempos)
print(timeit.repeat("result = []nfor p in proc:n if p not in fat:n result.append(p)", repeat=r, number=n, globals=globals()))
print(timeit.repeat('[ p for p in proc if p not in fat ]', repeat=r, number=n, globals=globals()))
print(timeit.repeat('list(set(proc) - set(fat))', repeat=r, number=n, globals=globals()))
Claro que os tempos podem variar conforme o hardware e outro fatores, e para listas pequenas - como as que você usou - a diferença será insignificante, mas no geral, usar set
se mostrou bem mais rápido. Na minha máquina os tempos foram (em segundos):
[1.4215344, 1.4107937, 1.4132282999999997]
[1.4147277999999996, 1.4120507999999994, 1.3960000999999993]
[0.015077500000000299, 0.014714099999999064, 0.015252100000001434]
Ou seja, usar set
foi, em geral, cerca de 100 vezes mais rápido. No Repl.it os resultados foram similares.
Answered by hkotsubo on November 13, 2021
Pelo que entendi do seu enunciado, você está precisando encontrar os valores que são comuns
às duas listas.
Se o que importar for o valor
do elemento, sem levar em consideração a quantidade
de ocorrências de cada elemento, podemos converter as duas listas para conjuntos
, calcular a intersecção dos conjuntos e, em seguida, exibir o resultado em uma nova lista. Para isso podemos utilizar o seguinte algoritmo...
proc = [1, 2, 3, 4]
fat = [3, 4, 5, 6]
proc = set(proc)
fat = set(fat)
inter = list(proc & fat)
print(inter)
Veja o funcionamento do algoritmo no repl.it.
Agora, se você pretendo exibir os elementos em ordem crescente de valores, você pode ordenar os valores na saída. Para isso aplicamos a função sorted
. Para isso basta utilizar o algoritmo...
proc = [1, 2, 3, 4]
fat = [3, 4, 5, 6]
proc = set(proc)
fat = set(fat)
inter = list(sorted(proc & fat))
print(inter)
Veja o funcionamento do algoritmo no repl.it.
Answered by Solkarped on November 13, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP