Is it possible to loop through operators (greater than/less than) in python?

Viewed 599

I want to be able to loop through relational operators. I have the following code working:

TP = df[(df.Truth == 1) & eval(df.age >= cutoff)]

I have a few more of these lines where the truth value and the relational operator is different but everything else is the same. I tried creating a list and using the eval function, but I know that's wrong since I can't even get past the syntax error.

truths = [[1,'>='],[0,'>='],[1,'<'],[0,'<']]
for truth in truths:
     truth_val = truth[0]
     operator = truth[1]
     TP = df[(df.Truth == truth) & eval(df.age operator cutoff)]

How do I go about looping the relational operator and not having python take it in as a string but as an actual operator? Thank you in advance!!!

3 Answers

If you want the actual operators, then you should use the operator library:

import operator as op

Then your code should look like this:

truths = [[1, op.ge], [0, op.ge], [1, op.lt], [0, op.lt]]
for truth in truths:
  truth_val = truth[0]
  operator = truth[1]
  TP = df[(df.Truth == truth) & operator(df.age, cutoff)]

This is the safest solution, all solutions based on eval are heavily discouraged, evaluating strings at runtime is a potential security issue.

Can you try

truths = [[1,'>='],[0,'>='],[1,'<'],[0,'<']]
for truth in truths:
     truth_val = truth[0]
     operator = truth[1]
     TP = df[(df.Truth == truth) & eval("df.age"+ operator + cutoff)] # notice cutoff here should be string

You need to provide eval() with a string:

truths = [[1,'>='],[0,'>='],[1,'<'],[0,'<']]
for truth in truths:
     truth_val = truth[0]
     operator = truth[1]
     print(eval(f"{df.age}{operator}{cutoff}"))
Related