2015-09-28 2 views
3

J'essaie d'utiliser la compréhension de liste pour recréer les résultats d'une fonction qui implique plusieurs instructions elif.Flux de contrôle de compréhension de liste

Mon programme est actuellement comme celui-ci

import numpy as np 

def myFunction(x): 
    result = [] 
    for num in x: 
     if num <= 0.5: 
      result.append(1) 
     elif num <= 0.75: 
      result.append(2) 
     elif num <= 0.9: 
      result.append(3) 
     else: 
      result.append(4) 

    return result 

u = np.random.uniform(0,1,1000) 

myFunction(u) 

Ce programme produit une liste de 1,2,3 ou 4 avec les probabilités appropriées. Je me demandais s'il y avait un moyen que je pourrais utiliser la compréhension de la liste pour effectuer la même tâche. Disons que l'on m'a donné un vecteur x = [1,2,3,4], mes résultats souhaités, et Prob = [0.5,0.75,0.9,1.0], la probabilité cumulative que l'événement ith se produise. Comment puis-je utiliser la compréhension de liste pour obtenir un résultat similaire?

je tente de faire quelque chose comme

[x[i] for num in u for i, test in enumerate(Prob) if num <= test] 

mais cela renvoie tous les éléments de xnum <= test et je veux que le premier.

J'espère que cela fait depuis et merci pour toute aide.

+0

Si vous voulez que la première occurrence vous pouvez envelopper votre compréhension de liste avec un appel de fonction 'next', par exemple:' next (x [i] pour num in u pour i, test dans énumération (Prob) si num <= test) '. Bien que je dois admettre que je ne suis pas tout à fait sûr si j'ai compris ce que vous voulez correctement – UnholySheep

+1

Lignes de code n'a jamais été une bonne mesure de logiciels pour presque n'importe quel but. En l'occurrence, votre bloc de code supérieur s'exécute beaucoup plus rapidement et est beaucoup plus lisible que les réponses proposées. – msw

Répondre

4

Vous pouvez utiliser next(iterable) à grand effet: next(outcome for outcome, prob in zip(x, Prob) if num <= prob) calculera le même numéro que le corps de votre boucle for:

def myFunction2(x): 
    outcomes = [1, 2, 3, 4] 
    probs = [0.5, 0.75, 0.9, 1.0] 
    result = [] 
    for num in x: 
     o = next(o for o, p in zip(outcomes, probs) if num <= p) 
     result.append(o) 
    return result 

Bien sûr, nous pouvons le poivre ceci avec une compréhension de la liste pour l'ensemble fonctionner un peu plus court:

def myFunction3(x): 
    outcomes = [1, 2, 3, 4] 
    probs = [0.5, 0.75, 0.9, 1.0] 
    result = [ 
     next(o for o, p in zip(outcomes, probs) if num <= p) 
     for num in x 
    ] 
    return result 
+2

Très intelligent, et illisible, et environ 6x plus lent que les ifs enchaînés de la poste d'origine. Je pensais que le zip et les deux boucles imbriquées vous coûteraient donc je l'ai testé. – msw

+0

Si la vitesse compte, utilisez la solution NumPy de Joran Beasley. Si vous voulez résoudre le problème en utilisant des itérateurs (ce qui est à peu près ce que le demandeur voulait), utilisez cette solution à la place. –

4

probabilités généralement somme à 1,0 par exemple probs = [0.5,0.25,0.15,0.1]

vous pouvez faire un peu chose vraiment facile

numpy.random.choice([1,2,3,4],p=probs) 

si elle était moi c'est la solution que j'utiliserais; P