按键值过滤字典列表 - 返回字典列表作为答案。

4

我有一个字典列表,我想要对其进行筛选。

[{"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}]

我的目标是获得包含两个字典的列表。一个字典具有“最高计数和正斜率”,另一个具有“最高计数和负斜率”。

我的计划是过滤所有正斜率和负斜率,然后对每个列表进行排序,接着创建一个由每个列表的第一条记录组成的新列表。

对列表进行排序对我来说不是问题,我能做到!

lines_lst.sort(key=lambda i: i['lines_count'])

但是当我尝试这样做时,过滤似乎不起作用,因为它返回一个字典。

positive_lines = next(item for item in lines_lst if item["Slope"] > 0)

有没有人能提供一种解决方案,最终得到以下结果?
[{"Slope": -0.562, "Count": 12},{"Slope": 2.5, "Count": 34}]
6个回答

6
你想要最大值和最小值...使用它们并应用合适的键函数 - 实际上,使用元组,你只需要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)

输出:

[{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]

元组按第一个值排序,然后是第二个值 - 您可以构建元组并将其用作max键函数。


@bradSolomon 那还需要更少的计算 - 我同意 - 但排序会让那些斜率为负且计数最少的排在后面 - 这不太符合需求吧? - Patrick Artner
它的效果非凡!!但是...事实证明,我可能并不总是拥有一对正负点。你知道我怎么把每个正斜率值和负斜率值按顺序放入列表中(按“计数”排序)吗?然后我就可以检查两者的长度并在此之后添加一些额外的条件了? - Lewis Morris
@Lew 你可能想采用BradSolomons或Vasilis的方法:列表推导式:a,b = sorted( (i for i in data if i["Slope"] < 0), key = lambda x:x["Count"]), sorted( (i for i in data if i["Slope"] >= 0), key = lambda x:x["Count"]) 或者使用 filter() 函数来实现相同的功能。但是你应该在其中一个情况下包括 "Slope" == 0,否则你将会消除这些值。 - Patrick Artner

2
您可以将 生成器表达式 传递给 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}

“当然,这个解决方案会对 lines_lst 进行两次迭代。如果你的输入非常大,你可以贪心地一次迭代并跟踪运行时的最大/最小值:”
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

但在 Python 领域中,只有当您的输入非常庞大且难以处理时,这可能才有价值。
请注意,在这两种情况下,对 max_pos/max_neg 的进一步修改构成了对 lines_lst 成员的修改,因为这些成员是可变字典。

1
你可以按照以下方式进行:
inList = [{"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}]

maximum = max(filter(lambda elem: elem['Slope'] > 0, inList), key=lambda e: e['Count'])
minimum = max(filter(lambda elem: elem['Slope'] < 0, inList), key=lambda e: e['Count'])

这将返回:
{'Slope': 2.5, 'Count': 34}
{'Slope': -0.562, 'Count': 12}

1
创建一个Count2键,对于负斜率则为负数。然后按Count2排序并取第一个和最后一个元素。
lines_lst = [{"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}]


for i in range(len(lines_lst)):
    lines_lst[i]['Count2'] = lines_lst[i]['Count']*lines_list[i]['Slope']/abs(lines_list[i]['Slope'])

lines_lst.sort(key=lambda i: i['Count2'])

[lines_lst[0], lines_lst[-1]]


1

针对Patrick答案中提供的额外信息,您可以按照以下步骤先对负面/正面列表进行排序:

positives = sorted((v for v in data if v['Slope'] >= 0), key=lambda x: x['Count'])
negatives = sorted((v for v in data if v['Slope'] < 0), key=lambda x: x['Count'])

# positives:
# [{'Slope': 1.52, 'Count': 2}, {'Slope': 0.56, 'Count': 6}, {'Slope': 2.5, 'Count': 34}]

# negatives:
# [{'Slope': -0.562, 'Count': 3}, {'Slope': -0.362, 'Count': 6}, {'Slope': -0.762, 'Count': 8}, {'Slope': -0.562, 'Count': 12}]

在这个点上获取最大值很简单。只需检索最后一个元素:

max_pox = positives[-1]     # {'Slope': 2.5, 'Count': 34}
max_neg = negatives[-1]     # {'Slope': -0.562, 'Count': 12}

或者,如果您更喜欢以列表形式:

[x[-1] for x in (negatives, positives)]

# [{'Slope': -0.562, 'Count': 12}, {'Slope': 2.5, 'Count': 34}]

0

这个可以工作吗?

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}]
positive_lines = []
negative_lines = []
for i in range(len(data)):
    if data[i]["Slope"] < 0:
        negative_lines.append(data[i])
    else:
        positive_lines.append(data[i])
max_counts = []
max_counts.append(max(positive_lines, key=lambda x:x['Count']))
max_counts.append(max(negative_lines, key=lambda x:x['Count']))
print(max_counts)

输出:

[{'Slope': 2.5, 'Count': 34}, {'Slope': -0.562, 'Count': 12}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接