Reputation: 799
I have following two lists:
advanced_filtered_list_val1 = [row for row in cleaned_list if float(row[val1]) < wert1]
advanced_filtered_list_val2 = [row for row in cleaned_list if float(row[val2]) < wert2]
How can I map the filtered lists in a list with the option and and/or or?
The data in the lists are dictionaries and I search and filter some rows in this lists. I want to filter two values on. This works fine. But how can I now map this to filter in a list?
I tried following things:
select = int(input())
#and operation
if select == 1:
mapped_list = [row for row in advanced_filtered_list_val1 and advanced_filtered_list_val2]
for x in mapped_list:
print(x)
#or operation
if select == 2:
mapped_list = [row for row in advanced_filtered_list_val1 or advanced_filtered_list_val2]
for x in mapped_list:
print(x)
I import the data as follows:
faelle = [{k: v for k, v in row.items()}
for row in csv.DictReader(csvfile, delimiter=";")]
I want to filter now from wert1
and wert2
and from wert1
or wert2
. Thats mean on the and
clause it should be on both filters true
, and on the or
clause it should one of wert1
or wert2
True
Upvotes: 2
Views: 85
Reputation: 6665
You want to filter dictionaries contained in cleaned_list
which respect either the two wert
-like conditions (AND) or at least one of them (OR). What you can do is
import operator as op
ineq_1 = 'gt'
ineq_2 = 'lt'
select = 2
andor = {
1:lambda L: filter(
lambda d: getattr(op,ineq_1)(float(d[val1]), wert1)
and getattr(op,ineq_2)(float(d[val2]), wert2),
L
),
2:lambda L: filter(
lambda d: getattr(op,ineq_1)(float(d[val1]), wert1)
or getattr(op,ineq_2)(float(d[val2]), wert2),
L
),
}
mapped_list = andor[select](cleaned_list)
for x in mapped_list:
print(dict(x))
The possible choices are gt
(greater than), lt
(lower than), or eq
.
and_
and or_
of the python-builtin module operator
. For example, doing
#Where the two following ix2-like stuffs are defined to make
# a correspondence between names one knows, and methods of the
# module operator.
ix2conj = {
1:'and_',
2:'or_',
}
ix2ineq = {
'<' :'lt',
'==':'eq',
'>' :'gt',
}
def my_filter(conjunction, inequality1, inequality2, my_cleaned_list):
return filter(
lambda d: getattr(op, ix2conj[conjunction])(
getattr(op, ix2ineq[inequality1])(float(d[val1]), wert1),
getattr(op, ix2ineq[inequality2])(float(d[val2]), wert2)
),
my_cleaned_list
)
ineq_1 = '>'
ineq_2 = '<'
select = 2
print(my_filter(select, ineq_1, ineq_2, cleaned_list))
Upvotes: 2
Reputation: 593
I see where you're coming from with that syntax, but that's not what the "and" and "or" keywords in python do at all. To do what you're looking for I think you'll want to use the built in type, set
. You could do something like
# note that this is already the "or" one
both = list1 + [x for x in list2 if not x in list1]
# for "and"
mapped_list = [x for x in both if x in list1 and x in list2]
If you want the resultant lists to have only unique values; otherwise you could just do the same with
both = list1 + list2
Upvotes: 0