Eu tenho uma lista de objetos. Eu quero encontrar um (primeiro ou qualquer outro objeto) nesta lista que tenha atributo (ou resultado do método - qualquer que seja) igual a value
.
Qual é a melhor maneira de encontrá-lo?
Aqui está o caso de teste:
class Test:
def __init__(self, value):
self.value = value
import random
value = 5
test_list = [Test(random.randint(0,100)) for x in range(1000)]
# that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
for x in test_list:
if x.value == value:
print "i found it!"
break
Eu acho que usar geradores e reduce()
não fará nenhuma diferença, porque ainda estaria percorrendo a lista.
ps .: A equação para value
é apenas um exemplo. Claro que queremos obter um elemento que atenda a qualquer condição.
Respostas:
Isso obtém o primeiro item da lista que corresponde à condição e retorna
None
se nenhum item corresponder. É o meu formulário de expressão única preferido.Contudo,
A versão ingênua de quebra de loop é perfeitamente Pythonic - é concisa, clara e eficiente. Para que ele corresponda ao comportamento de uma linha:
Isto irá atribuir
None
parax
se você não fazbreak
fora do circuito.fonte
... if getattr(x, x.fieldMemberName) == value
. Isso buscará o atributox
com o nome armazenadofieldMemberName
e o comparará comvalue
.else
cláusula deve estar nofor
loop, não noif
. (Edição rejeitada).Uma vez que não foi mencionado apenas para conclusão. O bom e velho filtro para filtrar seus elementos a serem filtrados.
Ftw de programação funcional.
Eu sei que geralmente na lista python é preferível a compreensão ou pelo menos é o que eu leio, mas não vejo a questão como honesta. É claro que o Python não é uma linguagem FP, mas Map / Reduce / Filter são perfeitamente legíveis e são os casos de uso mais padrão da programação funcional.
Então lá vai você. Conheça tua programação funcional.
lista de condições do filtro
Não será mais fácil do que isso:
fonte
filter
retorna uma lista que não é compatívelnext
. 2 : requer que haja uma correspondência definida; caso contrário, você receberá umaStopIteration
exceção.Um exemplo simples : temos a seguinte matriz
Agora, queremos encontrar o objeto na matriz que tenha um ID igual a 1
next
com compreensão de listaA saída de todos os métodos acima é
{'id': 1, 'name': 'ronaldo'}
fonte
Acabei de encontrar um problema semelhante e desenvolvi uma pequena otimização para o caso em que nenhum objeto da lista atende aos requisitos (para o meu caso de uso, isso resultou em grande melhoria de desempenho):
Junto com a lista test_list, mantenho um conjunto adicional test_value_set que consiste em valores da lista que eu preciso filtrar. Portanto, aqui a outra parte da solução da agf se torna muito rápida.
fonte
Você poderia fazer algo assim
Isso é o que eu uso para encontrar os objetos em uma longa variedade de objetos.
fonte
Você também pode implementar uma comparação rica via
__eq__
método para suaTest
classe e usar oin
operador. Não tenho certeza se essa é a melhor maneira independente, mas, se você precisar compararTest
instâncias com base emvalue
outro lugar, isso pode ser útil.fonte
Para o código abaixo, xGen é uma expressão geradora anônima, yFilt é um objeto de filtro. Observe que, para xGen, o parâmetro None adicional é retornado em vez de gerar StopIteration quando a lista estiver esgotada.
Resultado:
fonte