0

I need to use the following syntax to filter the list operations:

a = [ope for ope in operations if ope[0] == 1] 

The if statement condition is variable and may contain multiple conditions:

a = [ope for ope in operations if ope[0] == 1 and ope[1] == "test"] 

I use a function to build the condition and return it as a string:

>>>> c = makeCondition(**{"id": 1, "title": 'test'}) >>>> c "ope[0] == 1 and ope[1] == 'test'" 

Is there a way to integrate the c variable into the list filtering? Something like this (of course, the c variable is evaluated as a string in the below example):

 a = [ope for ope in operations if c] 

Thanks for help!

6
  • 1
    Have you tried a = [... if eval(c)]? Commented Dec 8, 2017 at 7:42
  • 1
    Why do you build the condition as a string? Making it a function or a lambda would make much more sense. Commented Dec 8, 2017 at 7:45
  • a = [... if eval(c)] does work, thanks @Chris! Consider adding your comment as an answer so that I can accept it. @tripleee: I don't get what you mean. Could you tell me more with a basic syntax example? Commented Dec 8, 2017 at 7:58
  • You could do conditions[0] = lambda ope : ope[0] == 1 and so on. Fill up a list with all the conditions as lambda functions inside, then in the list comprehension, select the one condition you want to use with a = [ope for ope in operations if conditions[0](ope)]. Commented Dec 8, 2017 at 8:11
  • Have your function return the logical result and not a string. Then you can use it in your test. Do not generate a strong of code and then use evel -- pretty much ever... Commented Dec 8, 2017 at 8:17

2 Answers 2

2

eval is considered unsafe and is generally avoided.

You can use [filter][1] with functions. For this you should put your test conditions in a function.

Here's an example to create a list of numbers between 1 and 100 that are multiples of 3 and 7

def mult3(n): return n % 3 == 0 def mult7(n): return n % 7 == 0 def mult3_and_7(n): return mult3(n) and mult7(n) list(filter(mult3_and_7, range(1, 101))) 

A more consice way is to use lambdas:

list(filter(lambda n: (n % 3 == 0) and (n % 7 == 0), range(1, 101)) 

The cool thing is you can chain filters like so:

list(filter(lambda n: n % 3 == 0, filter(lambda n: n % 7 == 0, range(1, 101)))) 

They all give [21, 42, 63, 84]

This approach should help you chain multiple conditions clearly.

Sign up to request clarification or add additional context in comments.

3 Comments

This helps, thanks! But in my case, I need to collect the values associated to each key from the dictionnary passed as a **kwargs, not just True or False values.
In your case, makeCondition seems to be hard coded with ope this means that it may be refactored to something like makeCondition(some_list, **kwargs) -> bool. Rather than return a string, the tests take place inside makeCondition. That way, you can eaisly do list(filter(makeCondition, ope)).
I have made another post related to that subject : stackoverflow.com/q/47769705/2508539. Thanks again!
0

As commented, if you want to change the string to be considered as an expression, you can use eval(string).

1 Comment

using eval is almost always the wrong solution. Here the problem can certainly be solved using lambdas instead

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.