2015-09-28 2 views
3

Я пытаюсь использовать понимание списка, чтобы воссоздать результаты функции, которая включает в себя несколько операторов elif.Список Контроль управления Поток

Моя программа в настоящее время, как этот

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) 

Эта программа производит список 1,2,3 или 4 с соответствующими вероятностями. Мне было интересно, есть ли способ, которым я мог бы использовать понимание списка для выполнения одной и той же задачи.

Предположим, что мне дали вектор x = [1,2,3,4], мои желаемые результаты и Prob = [0.5,0.75,0.9,1.0], кумулятивную вероятность того, что произойдет i-й случай. Как я могу использовать понимание списка, получаю аналогичный результат?

Я пытался сделать что-то вроде

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

но это возвращает все элементы x где num <= test, и я только хочу первый.

Я надеюсь, что это сделано с благодарностью за любую помощь.

+0

Если вы хотите только первое вхождение можно обернуть список вашего понимания с 'вызова next' функции, например:' next (x [i] для num in u for i, test in enumerate (Prob), если num <= test) '. Хотя я должен признать, что я не совсем уверен, правильно понял, что вы хотите – UnholySheep

+1

Линии кода никогда не были хорошей метрикой программного обеспечения практически для любых целей. Как это бывает, ваш верхний блок кода работает значительно быстрее и значительно читабельнее, чем предлагаемые ответы. – msw

ответ

4

Вы можете использовать next(iterable) с большим эффектом: next(outcome for outcome, prob in zip(x, Prob) if num <= prob) будет вычислять такое же количество, как тело вашего для цикла:

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 

Конечно, мы можем перец этого со списком пониманием, чтобы сделать весь работать немного короче:

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

Очень умный и нечитаемый, и примерно в 6 раз медленнее, чем прикованный ifs исходного сообщения. Я понял, что zip и два вложенных цикла будут стоить вам, поэтому я его протестировал. – msw

+0

Если скорость имеет значение, используйте решение на основе NumPy от Joran Beasley. Если вы хотите решить проблему с помощью итераторов (что примерно так и требовалось), используйте это решение. –

4

обычно вероятности суммы до 1,0 т probs = [0.5,0.25,0.15,0.1]

, то вы можете сделать некоторые вещь очень легко

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

, если это было мне, что это решение, которое я хотел бы использовать, P