Reman
Reman

Reputation: 8109

How to check if elements in list 'a' meet conditions in list 'b'?

I have a list of numbers:

a = [3, 6, 20, 24, 36, 92, 130]

And a list of conditions:

b = ["2", "5", "20", "range(50,100)", ">120"]

I want to check if a number in 'a' meets one of the conditions in 'b' and if yes, put these numbers in list 'c'

In above case:

c = [20, 92, 130]

I created this code what seems to do what I want:

c = []
for x in a:
    for y in b:
        if "range" in y:
            rangelist = list(eval(y))
            if x in rangelist:
                c.append(x)
        elif ">" in y or "<" in y:
            if eval(str(x) + y):
                c.append(x)
        else:
            if x == eval(y):
                c.append(x)

However my list 'a' can be very big.
Is there not an easier and faster way to obtain what I want?

Upvotes: 9

Views: 1511

Answers (4)

Roman Kulak
Roman Kulak

Reputation: 31

Based on previous answers, I think there could be 2 more ways.

#1
numbers = [3, 6, 20, 24, 36, 92, 130]
conditions = [
    lambda n: n == 2,
    lambda n: n == 5,
    lambda n: n == 20,
    lambda n: n in range(50, 100),
    lambda n: n > 120,
]
result = [num for num in numbers for condition in conditions if condition(num)]

#2
condition = lambda n: n in {2, 5, 20} or 50 <= n <= 100 or n > 120
result = list(filter(condition, numbers))

For a really big list, you should go with example #2 because it is more memory efficient and time complexity is linear instead of quadratic-like in #1

Upvotes: 2

Argus Malware
Argus Malware

Reputation: 787

you want simple ,pythonic and easy to grasp forget the above ones

a = [3, 6, 20, 24, 36, 92, 130]
[i for i in a if i==2 or i==5 or i==20 or i>120 or 50<=i<=100 ]

Upvotes: 2

Ganesh Tata
Ganesh Tata

Reputation: 1195

Building on @user2357112's suggestion, you can create a list of functions for all your conditions, then pass each number, to each function to determine whether the number meets any of the conditions, or not.

In [1]: a = [3, 6, 20, 24, 36, 92, 130]

In [2]: conditions = [lambda x:x==2, lambda x:x==5, lambda x:x==20, lambda x: x in range(50, 100), lambda x: x > 120]  # List of lambda functions

In [3]: output = list()

In [4]: for number in a:
   ...:     if any(func(number) for func in conditions): # Check if the number satisfies any of the given conditions by passing the number as an argument to each function
   ...:         output.append(number)         

In [5]: output
Out[5]: [20, 92, 130]

Upvotes: 13

Mureinik
Mureinik

Reputation: 311428

Assuming you could change b to hold valid conditions (when concatinated with elements from a) as discussed in the comments above:

b = ["==2", "==5", "==20", "in range(50,100)", ">120"]

You could concatinate each element of a with these conditions and use eval to check if it evaluates to True or False. This, of course, can be done in a list comprehension:

result = [i for i in a if any(eval(str(i) + x) for x in b)]

Upvotes: 4

Related Questions