1

I am trying to count the number of times the elements in my list 'predicted' equal the corresponding elements in my list 'actual' when said 'actual' elements equal 1 (the number of 'true positives').

Here's my code:

def F_approx(predicted, actual):
   est_tp = np.sum([int(p == a) if a for p in predicted for a in actual])
   est_fn = np.sum([int(p !=a) if a for p in predicted for a in actual])
   est_recall = est_tp / (est_tp + est_fn)
   pr_pred_1 = np.sum([int(p == 1) for p in predicted]) / len(predicted)
   est_f = np.power(est_recall, 2) / pr_pred_1
   return(est_f)

Which looks correct to my eye, but I get an error:

    File "<ipython-input-17-3e11431566d6>", line 2
       est_tp = np.sum([int(p == a) if a for p in predicted for a in actual])
                                           ^ 
    SyntaxError: invalid syntax

Thanks for the help.

Hudson Cooper
  • 75
  • 1
  • 8

2 Answers2

3

The if goes after the looping expression:

[int(p == a) for p in predicted for a in actual if a]

However, it really looks like you want to zip these together:

[int(p == a) for p, a in zip(predicted, actual)]
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Interesting, thank you. I just read an answer from http://stackoverflow.com/questions/17321138/python-one-line-list-comprehension-if-else-variants that seems to suggest the opposite (at least for an if else case). Why does it work there and not here? – Hudson Cooper Feb 17 '16 at 20:18
  • Never mind, I can answer my own question. This example is a filter, the other is not. – Hudson Cooper Feb 17 '16 at 20:19
  • 1
    List comprehensions have the following syntax (approximately): `[expression for var in loop_expression if filter_expression]`. Those expressions can be just about anything -- including "conditional expressions" which have the form: `expression if conditional else conditional`. Note that the `else` is required to make the conditional expression. – mgilson Feb 17 '16 at 20:20
  • 1
    @HudsonCooper -- Also note that if `predicted` and `actual` are `np.ndarray`, you can probably do: `np.sum(predicted == array)` as a shortcut :-) – mgilson Feb 17 '16 at 20:22
1

the if is placed at the end of the list comprehension

[int(p == a) for p in predicted for a in actual if a]

as a side note, with your particular construct you can add a ternary operation and have an else in your list comprehension

[int(p == a) if a else '' for p in predicted for a in actual if a]

adding else to the end of the list comprehension will throw a SyntaxError

danidee
  • 9,298
  • 2
  • 35
  • 55