如何比较同一 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
分组,使用 dict
和 d['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}]
我有一本字典,例如:
{
"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
分组,使用 dict
和 d['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}]