2015-01-29 2 views
-1

Я сделал немного кода, который добавляет результаты тестов из текстового файла в словарь питона в формате этого:Как узнать средние значения в словаре, которые назначены ключу?

{'Ruan': '22', 'hello': [22, 1], 'kurun': '29'} 

И я хочу работать в среднем всяких баллов и это это то, что я пытался до сих пор:

while choice == 'av': 
    if schClass == '1': 
    schClass = open("scores1.txt", 'r') 
    li = open("scores1.txt", 'r') 
    data = li.read().splitlines() 
    for li in data: 
     name = li.split(":")[0] 
     score = li.split(":")[1] 
     if name not in diction1: 
      diction1[name] = score 
     if name in diction1: 
        diction1[name] = [int(diction1[name]),int(score)]  
     print(diction1) 
     averages_dct = {} 
     for name in diction1: 
      student_average = sum((diction1[name]))/len((diction1[name])) 
      averages_dct.update({name: student_average}) 
     reversed_dct = {averages_dct[k]: [] for k in averages_dct} 
     for average in reversed_dct: 
      for name in averages_dct: 
       if average == averages_dct[name]: 
          reversed_dct[average].append(name) 
          for av in sorted(reversed_dct, reverse=True): 
           print('average: %s, students: %s' % (av, reversed_dct[av])) 

Это ошибка:

student_average = sum((diction1[name]))/len((diction1[name])) 
TypeError: unsupported operand type(s) for +: 'int' and 'str' 

Я гайка понять, что это означает, что в полной мере и не знаю, как исправить Это?

+0

вы не можете назвать сумму на Int –

+1

также подозреваю 'имя, оценка = li.split («:») 'будет работать и заменять dict с defaultdict –

+0

okay cheers @PadraicCunningham И что я делаю вместо суммы? –

ответ

0

Весьма неразумно смешивать обе строки и список целых чисел в структуре данных. Вместо этого вы должны попробовать что-то подобное. Это поможет дальнейшие расчеты:

while choice == 'av': 
    if schClass == '1': 
    schClass = open("scores1.txt", 'r') 
    li = open("scores1.txt", 'r') 
    data = li.read().splitlines() 
    for li in data: 
     name = li.split(":")[0] 
     score = li.split(":")[1] 

     diction1.setdefault(name,[]).append(int(score)) 

    # The following loop should work, 
    # even if it can be optimized (see Padraic's answer) 
    for name in diction1: 
     student_average = sum(diction1[name])/len(diction1[name]) 
     averages_dct[name] = student_average 
    ... 

Установите док в setdefault для деталей.

Поскольку я не имею входной файл данных, я не могу проверить это, но это должно производить что-то вроде этого:

{'Ruan': [22], 'hello': [22, 1], 'kurun': [29]} 

После того, что остальная часть кода должна работать теперь равномерно есть список целых чисел. Каково бы ни было количество «баллов» для того же игрока.

+0

ура вы помогли мне так много @Sylvain Leroux –

0

Не знаете, что делает весь код, но используя defaultdict и сохраняя все результаты в списке, будет легче суммировать и усреднить, defaultdict добавит имя и добавит, если этот ключ не существует или просто добавляет каждую оценку если это делает, это более эффективно, чем при использовании dict.setdefault:

from collections import defaultdict 


diction1 = defaultdict(list) 
averages_dct = {} 
student_average = {} 
while choice == 'av': # 
    if schClass == '1': # not sure what this is supposed to do 
     schClass = open("scores1.txt", 'r') 
    with open("scores1.txt") as f: 
     for li in f: # just iterate over the file object 
      name, score = li.split(":") # split once and unpack 
      # append score cast as int to the list 
      diction1[name].append(int(score)) 
    # now average scores for each using calling sum on lists of ints 
    for name,scores in diction1.items(): 
     student_average = sum(scores)/len(scores) 
     averages_dct[name] = student_average 

Я полагаю, ваш следующий цикл, чтобы найти имена с тем же средним баллом так же мы можем использовать defaultdict, используя средние значения в качестве ключей и добавления имен, которые имеют те среднее значение:

common_dct = defaultdict(list) 
# use items to get the key and value 
for name, average in averages_dct.items(): 
    common_dct[averages_dct].append(name) 

Если вы не хотите использовать common_dict, вы можете группировать имена в предыдущем цикле, перестраивая логику, используя оценки как ключи и добавляющие имена.

Вы можете также позволить statistics модуль заботиться о среднем заменяющего код:

from statistics import mean 
for name,scores in diction1.items(): 
    student_average = mean(scores) 
    averages_dct[name] = student_average 
Смежные вопросы