Une solution (le meilleur si vous avez répété la valeur de x) serait à memoize la fonction f, c'est à dire de créer une fonction wrapper qui permet d'économiser l'argument par lequel la fonction est appelée et de l'enregistrer, de le retourner si la même valeur est demandé.
l'une, très simple de mise en œuvre est la suivante:
storage = {}
def memoized(value):
if value not in storage:
storage[value] = f(value)
return storage[value]
[memoized(x) for x in l if memoized(x)]
et ensuite utiliser cette fonction dans la compréhension de liste. Cette approche est valable que sous deux conditions, l'une théorique et une pratique. La première est que la fonction f doit être déterministe, c'est à dire renvoie les mêmes résultats à la lumière de la même entrée, et l'autre est que l'objet x peut être utilisé comme un dictionnaire clés. Si le premier n'est pas valide, vous devez recalculer f chaque timeby définition, tandis que si le second échoue, il est possible d'utiliser certains un peu plus robuste approches.
Vous pouvez trouver beaucoup de mise en œuvre de memoization sur le net, et je pense que les nouvelles versions de python ont quelque chose inclus dans eux trop.
Sur une note de côté, n'utilisez jamais le petit L comme un nom de variable, est une mauvaise habitude, comme elle peut être confondue avec un i ou un 1 sur certains terminaux.
EDIT:
comme indiqué, une solution possible à l'aide de générateurs de compréhension (pour éviter de créer inutile de dupliquer temporaires) serait de cette expression:
[g(x, fx) for x, fx in ((x,f(x)) for x in l) if fx]
Vous avez besoin de poids de votre choix compte tenu du coût de calcul de f, le nombre de doublons dans la liste d'origine et de la mémoire à vous disposition. Memoization faire un espace-vitesse, ce qui signifie qu'il garder des morceaux de chaque résultat de l'enregistrer, donc si vous avez des grandes listes elle peut devenait coûteux sur la mémoire de l'occupation avant.