2017-09-19 1 views
3

J'ai donc quelques compréhensions de liste qui ressemblent à ceci.Compréhension de liste avec calcul coûteux

li = [some_computation(x) for x in y if some_computation(x)] 

Où je veux que les valeurs qui sont truthy par rapport à some_computation.

  1. Est-ce que cela calcule deux fois some_computation(x) comme la compréhension de la liste semble le faire? Si some_computation est cher, je vraiment ne veulent pas veulent cela. (Je pense que c'est probablement le cas :()
  2. Y at-il une meilleure façon de le faire? Peut-être de le casser dans une boucle régulière et ajouter si seulement si some_computation(x), mais j'aime les compréhensions.
+2

Cela est venu plusieurs fois avant, mais semblent ne peut le trouver ... de toute façon ... vous pouvez imbriquer un gen-exp dans votre liste-maquette, par exemple: 'li = [el pour el dans (some_func (x) pour x dans y) si el] '... –

+0

Oui, la fonction' some_computation' sera évaluée deux fois dans Python 2.x et 3.x – Jaco

+0

@JonClements Je pense avoir trouvé c'est ici: https: // stackoverflow.com/questions/130262/how-do-i-efficace-filter-calculé-values-within-a-python-list-comprehension? rq = 1 Merci pour votre réponse! –

Répondre

4

some_computation sera calculé deux fois, pour éviter cela, vous pouvez utiliser filter pour annuler les résultats falsy:

li = list(filter(None, (some_computation(x) for x in y))) 

Ou utiliser une expression generator imbriqué comme Jon Clements suggère:

li = [el for el in (some_computation(x) for x in y) if el] 
0
  1. Est-ce que cela calcule some_computation (x) deux fois que la compréhension de la liste le fait apparaître?

Oui. Il calcule deux fois.

  1. Existe-t-il une meilleure façon de procéder? Peut-être de le casser en une boucle normale et d'ajouter si seulement some_computation (x), mais j'aime les compréhensions.

Vous devez faire une boucle régulière. Les générateurs sont à la volée et ne sont pas stockés. Peut-être que vous pouvez prendre l'algorithme pour les x chosing out et faire le calcul

li = [computation(x) for x in y if choose(x)] 

Ou vous avez à faire itération dans la condition if qui équivaut à appeler le calcul deux fois.

1
  1. Oui, il ne some_computation deux fois, essayez et voyez:

    def compute(x): 
        print("Compute...") 
        return 2*x 
    y=[1,3,5] 
    ls=[compute(x) for x in y if compute(x)] 
    

Sortie:

Compute... 
Compute... 
Compute... 
Compute... 
Compute... 
Compute... 
  1. Mieux Python chemin:

    ls=[x for x in [compute(z) for z in y] if x]