Итерация по вложенному списку и вычисление средних значений элементов - PullRequest
0 голосов
/ 23 октября 2018

Используя API Riot, я разрабатываю приложение, которое анализирует данные из истории матчей игроков League of Legends.


У меня есть список, содержащий наименования предметов и время покупки (в секундах)

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] до его инициализации.


На данный момент я немного застрял.Любые указатели или помощь будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

С вашим подходом связаны две проблемы: ту, которую вы определили, и то, что если элемент встречается три раза, среднее значение вычисляется неправильно.Чтобы исправить это, одним из подходов является суммирование времен, а также запись количества случаев отдельно, а затем вычисление среднего значения в качестве второго шага.

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))
0 голосов
/ 23 октября 2018

Сначала я заполнил бы словарь, и для каждого 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

Решение Дэниела делает то же самое, в более питоническом и эффективном виде.

0 голосов
/ 23 октября 2018

Вы можете использовать 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()])

Или как альтернативное использование 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]]
...