I have a list of dictionaries that I want to filter.
[{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
My goal is to get a list of two dictionaries. One with the "highest count and a POSITVE slope" and the other with the "highest count and NEGATIVE slope".
My plan was to filter all the positive and negative ones out, then sort each list and then create a new list with the first record of each.
Sorting the list isnt an issue for me, i've got this!
lines_lst.sort(key=lambda i: i['lines_count'])
But filtering doesn't seem to work when I try this as it returns a dictionary.
positive_lines = next(item for item in lines_lst if item["Slope"] > 0)
Does anyone have a solution that ends up with the below?
[{"Slope": -0.562, "Count": 12},{"Slope": 2.5, "Count": 34}]
You want max and min .. use them and apply a suitable key function - in fact using tuples you only need max:
data = [{"Slope": -0.562, "Count": 3},
{"Slope": -0.362, "Count": 6},
{"Slope": -0.762, "Count": 8},
{"Slope": -0.562, "Count": 12},
{"Slope": 2.5, "Count": 34},
{"Slope": 1.52, "Count": 2},
{"Slope": .56, "Count": 6}]
m1 = max(data, key= lambda x: (x["Slope"]>0, x["Count"]))
m2 = max(data, key= lambda x: (x["Slope"]<0, x["Count"]))
result = [m1,m2]
print(result)
Output:
[{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]
Tuples sort by 1st value, then second value - you can build tuples and use them as max key function.
You can pass a generator expression to max()
:
>>> max((d for d in lines_lst if d["Slope"] > 0), key=lambda d: d["Count"])
{'Slope': 2.5, 'Count': 34}
>>> max((d for d in lines_lst if d["Slope"] < 0), key=lambda d: d["Count"])
{'Slope': -0.562, 'Count': 12}
Granted, this solution iterates through lines_lst
twice. If you have a really large input, you could iterate through it once, greedily, keeping track of the running max/min:
import sys
max_pos, max_neg = {"Count": -sys.maxsize}, {"Count": -sys.maxsize}
for d in lines_lst:
ct = d["Count"]
if d["Slope"] > 0 and ct > max_pos["Count"]:
max_pos = d
elif d["Slope"] < 0 and ct > max_neg["Count"]:
max_neg = d
But in Python-land, this is probably only valuable if your input is really large and unwieldy.
Note that in both these cases, _further modifications to max_pos
/max_neg
constitute modifications to the members of lines_lst
, because those members are mutable dictionaries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With