遍历嵌套列表并计算元素的平均值

Iterate through nested list and calculate the average values of elements

使用 Riot 的 API,我正在开发一个应用程序来分析玩家英雄联盟比赛历史的数据。


我有一个包含商品名称购买时间(以秒为单位)

的列表
item_list =
[['Boots of Speed', 50], 
['Health Potion', 60], 
['Health Potion', 80],
['Dorans Blade', 120],  
['Dorans Ring', 180], 
['Dorans Blade', 200], 
['Dorans Ring', 210]]

我正在尝试将其转换为包含项目名称的项目的唯一列表平均购买时间

对于这个例子,这就是我要将我的列表转换成的内容:

['Boots of Speed', 50]
['Health Potion', 70]
['Dorans Blade', 160]
['Dorans Ring', 195]

我尝试的解决方案是创建一个空字典,遍历列表,将字典键设置为项目名称,将平均时间设置为键值。

dict = {}
for item in item_list:
    item_name = item[0]
    time_of_purchase = item[1]
    dict[item_name] = (dict[item_name] + time_of_purchase) / 2 # Would cast this as an integer

这个问题是我将尝试在变量 dict[item_name] 初始化之前对其进行计算。


此时我有点卡住了。任何指点或帮助将不胜感激。

您可以使用 setdefault:

item_list = [['Boots of Speed', 50],
             ['Health Potion', 60],
             ['Health Potion', 80],
             ['Dorans Blade', 120],
             ['Dorans Ring', 180],
             ['Dorans Blade', 200],
             ['Dorans Ring', 210]]

result = {}
for item, count in item_list:
    result.setdefault(item, []).append(count)

print([[key, sum(value) / len(value) ] for key, value in result.items()])

或者作为替代使用 collections 模块中的 defaultdict

from collections import defaultdict

item_list = [['Boots of Speed', 50],
             ['Health Potion', 60],
             ['Health Potion', 80],
             ['Dorans Blade', 120],
             ['Dorans Ring', 180],
             ['Dorans Blade', 200],
             ['Dorans Ring', 210]]

result = defaultdict(list)
for item, count in item_list:
    result[item].append(count)

print([[key, sum(value) / len(value) ] for key, value in result.items()])

输出

[['Dorans Blade', 160.0], ['Boots of Speed', 50.0], ['Health Potion', 70.0], ['Dorans Ring', 195.0]]

您的方法有两个问题,一个是您确定的,另一个是如果该项目出现三次,则平均值计算不正确。要解决此问题,一种方法是对次数求和,但也分别记录出现的次数,然后计算平均值作为第二步。

item_list = [['Boots of Speed', 50],
['Health Potion', 60],
['Health Potion', 80],
['Dorans Blade', 120],
['Dorans Ring', 180],
['Dorans Blade', 200],
['Dorans Blade', 200],
['Dorans Blade', 200],
['Dorans Ring', 210]]

item_dict = {}
for item in item_list:
    item_name = item[0]
    time_of_purchase = item[1]
    if (item_name in item_dict):
        # Add the duplicate item in
        item_dict[item_name] = item_dict[item_name][0] + time_of_purchase, item_dict[item_name][1] + 1
    else:
        # First time recording this item
        item_dict[item_name] = (time_of_purchase, 1)

for item_name in item_dict.keys():
    purchase_time = item_dict[item_name][0]
    purchase_count= item_dict[item_name][1]
    print("%-15s - %u" % (item_name, purchase_time/purchase_count))

我会先填写字典,对于每个 item_name 我会有一个 time_of_purchase 值的列表。完成后,我将遍历字典(键,列表)对,并计算每个列表的平均值。

item_list = [['Boots of Speed', 50],
['Health Potion', 60],
['Health Potion', 80],
['Dorans Blade', 120],
['Dorans Ring', 180],
['Dorans Blade', 200],
['Dorans Ring', 210]]

# Fill the dictionary
d = {}
for item in item_list:
    item_name, time_of_purchase = item
    if item_name not in d:
        d[item_name] = []
    d[item_name].append(time_of_purchase)

# Now calculate and print the average
retlist = []
for item_name, list_of_times in d.items():
    new_entry = [
        item_name,
        sum(list_of_times) // len(list_of_times),
    ]
    retlist.append(new_entry)
print retlist

Daniel 的解决方案以更 pythonic 和高效的方式做同样的事情。