Reputation: 8109
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
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
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
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
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