[英]Python function to sum integer values based on string values in a nested dictionary?
The following is a subset of the data that I have:以下是我拥有的数据的子集:
VALID_CAR_NAMES = ['Audi', 'Holden', 'Honda', 'Mitsubishi', 'Toyota', 'Volvo']
car_data = {
'1': {'Name': 'Emily', 'CarName': 'Toyota', 'Price': '1000'},
'2': {'Name': 'John', 'CarName': 'Audi', 'Price': '30000'},
'3': {'Name': 'Ben', 'CarName': 'Audi', 'Price': '35000'},
'4': {'Name': 'Jasmine', 'CarName': 'Holden', 'Price': '17000'},
'5': {'Name': 'Tara', 'CarName': 'Mitsubishi', 'Price': '1000'},
'6': {'Name': 'Kristy', 'CarName': 'Mitsubishi', 'Price': '1500'},
'7': {'Name': 'Eddy', 'CarName': 'Honda', 'Price': '2000'},
'8': {'Name': 'Brett', 'CarName': 'Honda', 'Price': '2500'}
}
Here I'm trying to find the sum of the price column for each car in the list VALID_CAR_NAMES.在这里,我试图找到列表 VALID_CAR_NAMES 中每辆车的价格列的总和。 And if there is no data for a car in VALID_CAR_NAMES, the sum will be None.如果 VALID_CAR_NAMES 中没有汽车的数据,则总和将为 None。
The output should look like this (eg here the sum for Volvo is None because there's no data for it in the input dictionary car_data): output 应该如下所示(例如,这里沃尔沃的总和为 None,因为输入字典 car_data 中没有它的数据):
{
'Audi': {'sum': 65000},
'Holden': {'sum': 17000},
'Honda': {'sum': 4500},
'Mitsubishi': {'sum': 2500},
'Toyota': {'sum': 1000},
'Volvo': {'sum': None}
}
So here's a function that I've tried to write.所以这是我尝试编写的 function。 If I get rid of the else statement, it will sum up the prices for each car.如果我去掉 else 语句,它将总结每辆车的价格。 But when I run the code with the else statement (to change the 0 into None for cars with missing/no data), I end up getting "TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'".但是,当我使用 else 语句运行代码时(对于缺少/没有数据的汽车,将 0 更改为 None),我最终得到“TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int' ”。 This leads me to think my approach is wrong...这让我觉得我的方法是错误的......
def sum_car_price(car_data):
sum_car_price_dict = {'Toyota': {'sum': 0}, 'Audi': {'sum': 0}, 'Holden': {'sum': 0},\
'Mitsubishi': {'sum': 0}, 'Honda': {'sum': 0}, 'Volvo': {'sum': 0}}
for car_id, customer_data in car_data.items():
for car_name, car_price in sum_car_price_dict.items():
if customer_data['CarName'] in car_name:
car_price['sum'] += int(customer_data['Price'])
else:
car_price['sum'] = None
return sum_car_price_dict
You gotta love lambdas, generators and list comprehensions:你必须喜欢 lambdas、生成器和列表推导:
prices = lambda c: (int(cd["Price"]) for cd in car_data.values() if cd["CarName"] == c)
x = {c: {"sum": sum(prices(c)) or None} for c in VALID_CAR_NAMES}
def sum_car_price(car_data):
"""This function takes a dictionary of clean data (car_data) and
finds the sum total price for each car in the list VALID_CAR_NAMES.
The return value is a dict with the sum price for each car"""
sum_car_price_dict = {'Toyota': {'sum': None}, 'Audi': {'sum': None}, 'Holden': {'sum': None}, 'Mitsubishi': {'sum': None}, 'Honda': {'sum': None}, 'Volvo': {'sum': None}}
for car_id, customer_data in car_data.items():
if customer_data['CarName'] in VALID_CAR_NAMES:
if sum_car_price_dict[customer_data['CarName']]['sum'] == None:
sum_car_price_dict[customer_data['CarName']]['sum'] = customer_data['Price']
else:
sum_car_price_dict[customer_data['CarName']]['sum'] += customer_data['Price']
return sum_car_price_dict
You could just pre-initialize the dictionary with None values beforehand, and then simply check if it is already None, and act accordingly.您可以预先使用 None 值预先初始化字典,然后简单地检查它是否已经是 None,并采取相应的行动。
how about this?这个怎么样?
def sum_car_price(car_data):
result = {}
for car in VALID_CAR_NAMES:
data = [int(c["Price"]) for c in car_data.values() if c["CarName"]==car]
result[car] = {"sum":sum(data ) if data else None}
return result
def sum_car_price(car_data):
"""
This function takes a dictionary of clean data (car_data) and
finds the sum total price for each car in the list VALID_CAR_NAMES.
The return value is a dict with the sum price for each car
"""
# initialize all valid cars' count to 0
sum_car_price_dict = dict( (key, {'sum': 0}) for key in VALID_CAR_NAMES)
# iterate through all the data
for car_id, customer_data in car_data.items():
car_name = customer_data['CarName']
if car_name in VALID_CAR_NAMES:
try:
sum_car_price_dict[car_name]['sum'] += int(customer_data['Price'])
except KeyError:
pass
for value in sum_car_price_dict.values():
if value['sum'] == 0:
value['sum'] = None
return sum_car_price_dict
The problem is, you should not directly add an int
to None
in mid-way.问题是,您不应该在中途直接将int
添加到None
。
Considering your requirement, this should work.考虑到您的要求,这应该可行。 Main reason for the error is your order of nesting the for loops.错误的主要原因是您嵌套 for 循环的顺序。
for car_name, car_price in sum_car_price_dict.items():
for car_id, customer_data in car_data.items():
if customer_data['CarName'] == car_name:
car_price['sum'] += int(customer_data['Price'])
if (car_price['sum'] == 0):
car_price['sum'] = None
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.