如何比较同一 python 字典中的值并在匹配时执行操作

How to compare values in the same python dictionary and do stuff if match

我有一本字典,例如:

{
     "number_1":
    {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "number_2":
    {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "number_3":
    {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
    "number_4":
    {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
}

我需要一个 generic 方法来获取值的总和,如果字典对键 month_year 具有相同的值所以例如 month_year 5/2022 它会是:

{
    "month_year": "5/2022",
    "total_price": 2,
    "total_average": 2,
    "total_covered": 2,
}

与您可能已经看到的其他答案一样,您的词典格式不正确。因为您的 sub-dictionaries 在字典中,所以您也必须给它们一个键。这是一个例子:

{
    "1st Dictionary": {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "2nd Dictionary": {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "3rd Dictionary": {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
    "4th Dictionary": {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
}

在这里,您要给每个 sub-dictionary 一把钥匙。每个键简单地说明它是词典词典中的哪个词典。这是另一种方法:

{
    0: {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    1: {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    2: {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
    3: {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
}

除了您使用的是数字 0-3 之外,这是相同的事情。这可能是一个更好的主意,因为这样您就可以提供类似于索引的键。

现在回到你的问题!如果你想获得这些字典中任何一个的某个索引,你首先必须用所述字典定义一个变量,然后在变量旁边的括号内键入键(类似于列表)。为简单起见,我将使用第一本词典。这就是我要说的:

dictionary={
    "1st Dictionary": {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "2nd Dictionary": {
        "month_year": "5/2022",
        "price": 1,
        "average": 1,
        "covered": 1,
    },
    "3rd Dictionary": {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
    "4th Dictionary": {
        "month_year": "4/2022",
        "price": 10,
        "average": 93,
        "covered": 100,
    },
}

if dictionary["1st Dictionary"]["price"]>1:
    print("if statement ran successfully!")

elif dictionary["1st Dictionary"]["price"]==1:
    print("elif statement ran successfully!")

这里,输出为:elif语句运行成功!

我们在这里做的是获取名为 “1st Dictionary” 的键,然后在所述字典中获取名为 “price” 的键。以下是此行为的列表示例:

my_list=[
    [1,2,3],
    ["a","b","c"],
    [0.1,0.2,0.3]
]

if my_list[0][1]==2:
    print("if statement ran successfully!")

如果我们运行这段代码,我们得到输出:if语句运行成功!

这里我们检查 my_list 中第一个列表中的第二个索引是否等于 2。为了澄清起见,这里你可以看到 my_list 的第一个索引是 [1,2,3],而my_list的第一个索引的第二个索引是2.

my_list[0]==[1,2,3]

my_list[0][1]==2

希望这能以简单且 easy-to-understand 的方式回答您的问题!

您可以尝试以下解决方案 如果您有类似的相邻键,请尝试@steff 解决方案

#假设你有字典列表 bcz 由于不可散列的类型字典,字典集是不可能的

a = [{"month_year": "5/2022","price": 1,"average": 1,"covered": 1,
    },{"month_year": "5/2022","price": 1,"average": 1,"covered": 1,},{"month_year": "4/2022","price": 10,"average": 93,"covered": 100,},{"month_year": "4/2022","price": 10,"average": 93,"covered": 100,},]

from itertools import groupby
from collections import Counter

a.sort(key=lambda x: x["month_year"]) # We need to do this because groupby needs data in sorted manner
print([ {**sum((Counter(vals) for vals in val if (_:=vals.pop("month_year")) and (not print(vals))), Counter()), **{"month_year": key}} for key, val in groupby(a, key=lambda x: x["month_year"])])

# output [{'price': 20, 'average': 186, 'covered': 200, 'month_year': '4/2022'}, {'price': 2, 'average': 2, 'covered': 2, 'month_year': '5/2022'}]

解释:首先使用键 month_year 进行分组,我们得到 month_year 的唯一键和我们应用的那个组的值列表(使用 Counter 的两个字典的总和)然后将我的密钥放回生成的字典中。

您可以将具有相同 d['month_year'] 值的所有元素 d 分组,使用 dictd['month_year'] 作为键。

data = {
     "number_1":
    {"month_year": "5/2022", "price": 1, "average": 1, "covered": 1},
    "number_2":
    {"month_year": "5/2022", "price": 1, "average": 1, "covered": 1},
    "number_3":
    {"month_year": "4/2022", "price": 10, "average": 93, "covered": 100},
    "number_4":
    {"month_year": "4/2022", "price": 10, "average": 93, "covered": 100},
}

result = {}
for d in data.values():
    if d['month_year'] in result:
        for k in ('price', 'average', 'covered'):
            result[d['month_year']][k] += d[k]
    else:
        result[d['month_year']] = dict(d)

print(result)
# {'5/2022': {'month_year': '5/2022', 'covered': 2, 'price': 2, 'average': 2},
#  '4/2022': {'month_year': '4/2022', 'covered': 200, 'price': 20, 'average': 186}}

我认为现有的答案要么过于复杂,要么不够通用。这应该适用于所有新字段(假设它们仍然是数字),并依赖内置 collections 来完成大部分繁重的工作。

from collections import defaultdict, Counter

def group(mappings):
    dict_by_date = defaultdict(Counter)
    for mapping in mappings.values():
        date = mapping["month_year"]
        fields = {k: v for k, v in mapping.items() if k != "month_year"}
        dict_by_date[date].update(fields)
    return [{"month_year": date, **fields} for date, fields in dict_by_date.items()]

示例结果:

>>> from pprint import pprint
>>> pprint(group(test))
[{'average': 2, 'covered': 2, 'month_year': '5/2022', 'price': 2},
 {'average': 186, 'covered': 200, 'month_year': '4/2022', 'price': 20}]