Tengo una lista de objetos. Quiero encontrar un objeto (primero o lo que sea) en esta lista que tenga un atributo (o resultado del método, lo que sea) igual a value
.
¿Cuál es la mejor manera de encontrarlo?
Aquí está el caso de prueba:
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
Creo que usar generadores y reduce()
no hará ninguna diferencia porque todavía estaría iterando a través de la lista.
ps .: La ecuación de value
es solo un ejemplo. Por supuesto, queremos obtener un elemento que cumpla con cualquier condición.
Respuestas:
Esto obtiene el primer elemento de la lista que coincide con la condición, y regresa
None
si ningún elemento coincide. Es mi forma de expresión única preferida.Sin embargo,
La ingenua versión de loop-break es perfectamente pitónica: es concisa, clara y eficiente. Para que coincida con el comportamiento del one-liner:
Esto se asignará
None
ax
si no sebreak
sale del ciclo.fuente
... if getattr(x, x.fieldMemberName) == value
. Eso buscará el atributox
con el nombre almacenadofieldMemberName
y lo comparará convalue
.else
cláusula está destinada a estar en elfor
bucle, no a laif
. (Edición rechazada).Dado que no se ha mencionado solo para su finalización. El buen filtro para filtrar los elementos que se filtrarán.
Programación funcional ftw.
Sé que, en general, en la lista de Python se prefieren las comprensiones o al menos eso es lo que leo, pero no veo el problema para ser sincero. Por supuesto, Python no es un lenguaje FP, pero Map / Reduce / Filter son perfectamente legibles y son los casos de uso más estándar en programación funcional.
Ahí vas. Conoce tu programación funcional.
lista de condiciones de filtro
No será más fácil que esto:
fuente
filter
devuelve una lista que no es compatible connext
. 2 : requiere que haya una coincidencia definitiva, de lo contrario obtendrá unaStopIteration
excepción.Un ejemplo simple : tenemos la siguiente matriz
Ahora, queremos encontrar el objeto en la matriz que tiene una identificación igual a 1
next
con comprensión de listaLa salida de todos los métodos anteriores es
{'id': 1, 'name': 'ronaldo'}
fuente
Me encontré con un problema similar e ideé una pequeña optimización para el caso en el que ningún objeto en la lista cumple con el requisito (para mi caso de uso esto resultó en una mejora importante del rendimiento):
Junto con la lista test_list, mantengo un conjunto adicional test_value_set que consta de valores de la lista que necesito filtrar. Entonces, aquí la otra parte de la solución de agf se vuelve muy rápida.
fuente
Podrías hacer algo como esto
Eso es lo que uso para encontrar los objetos en una larga variedad de objetos.
fuente
También podría implementar una rica comparación a través del
__eq__
método para suTest
clase y usar elin
operador. No estoy seguro de si esta es la mejor manera independiente, pero en caso de que necesite compararTest
instancias basadas envalue
otro lugar, esto podría ser útil.fuente
Para el siguiente código, xGen es una expresión generadora anónima, yFilt es un objeto de filtro. Tenga en cuenta que para xGen se devuelve el parámetro None adicional en lugar de lanzar StopIteration cuando se agota la lista.
Salida:
fuente