Atajo O-cadena aplicada en la lista

Me gustaría hacer algo como esto:

x = f(a[0]) or f(a[1]) or f(a[2]) or f(a[3]) or … 

con una lista dada y una función dada f . A diferencia de la función incorporada, necesito obtener el primer valor de la lista que se considera verdadero; así que para 0 or "foo" or 3.2 necesito obtener "foo" , no solo True .

Por supuesto, podría escribir una pequeña función como

 def returnFirst(f, a): for i in a: v = f(i) if v: return v return False x = returnFirst(f, a) 

pero probablemente esa no sea la mejor solución, por razones también dadas en esta pregunta de SO . Como menciono este otro hilo, por supuesto podría usar código basado en la solución que se encuentra allí, por ejemplo,

 x = next((f(x) for x in a if f(x)), False) 

Pero no veo una manera simple de sortear la doble llamada de f ese momento.

¿Hay alguna solución simple que me esté perdiendo o que simplemente no sepa? Algo como un

 OR((f(x) for x in a)) 

¿tal vez?

Traté de encontrar otras preguntas relacionadas con esto, pero buscar palabras clave como or es un poco problemático en SO, así que tal vez no encontré algo apropiado.

Esto debería funcionar:

 next((x for y in a for x in (f(y),) if x),False) 

Ahora estoy usando esto:

 x = next((v for v in (f(x) for x in a) if v), False) 

Es un lenguaje de trabajo sin duplicar la llamada de f y sin introducir un hacky local, pero aún no es muy legible (especialmente si x , f , a v son más largas que una letra).

Me encantaría saber de una mejor solución.