简体   繁体   中英

How to iterate over list of sets and converting it to a dictionary in Python3

I have an input in the following format and I need to traverse through it to convert the given set into a dictionary.

input = [{"Bob","87"}, {"Mike", "35"},{"Bob", "52"}, {"Jason","35"}, {"Mike", "55"}, {"Jessica", "99"}]

My end goal is to have the average of every student in the dictionary form.

I tried doing it:

marks_dict ={}
for k,v in marks:
    if k not in marks_dict.keys():
        marks_dict[k] = v
    else:
        marks_dict[k].append(v)

print(marks_dict.keys())```

I am getting in output: 
'87': 'Bob', '35': 'Mike', '52': 'Bob', 'Jason': '35', 'Mike': '55', '99': 'Jessica'}
sometimes :
Traceback (most recent call last):
  File "/Users/rbhutada/Desktop/GSTest.gyp", line 7, in <module>
    marks_dict[k].append(v)
AttributeError: 'str' object has no attribute 'append'

Sets are by definition unordered. So {"Bob", "87"} is identical to {"87", "Bob"} .

So you don't want to use sets. Use tuples (or lists) instead, as they are ordered:

input = [("Bob","87"), ("Mike", "35"),("Bob", "52"), ("Jason","35"), ("Mike", "55"), ("Jessica", "99")]

Also, when you initialize a key, use a list [v] instead of the scalar v :

    if k not in marks_dict.keys():
        marks_dict[k] = [v]

Otherwise you cannot append to it later.

So the code becomes (with input changed to marks so it fits with the code):

marks = [("Bob","87"), ("Mike", "35"),("Bob", "52"), ("Jason","35"), ("Mike", "55"), ("Jessica", "99")]

marks_dict ={}
for k,v in marks:
    if k not in marks_dict.keys():
        marks_dict[k] = [v]
    else:
        marks_dict[k].append(v)

print(marks_dict.keys())
print(marks_dict)

with this output:

dict_keys(['Bob', 'Mike', 'Jason', 'Jessica'])
{'Bob': ['87', '52'], 'Mike': ['35', '55'], 'Jason': ['35'], 'Jessica': ['99']}

From there I will leave it to you to calculate the averages.

I do suggest using integers from the beginning for the marks, though, instead of strings, if they are all integers. So 87 instead of "87" , for instance.

If you really happen to have sets in a list, you need to convert it to an easier to handle data type before. Afterwards, you may use itertools.groupby :

from itertools import groupby

lst = [{"Bob", "87"}, {"Mike", "35"}, {"Bob", "52"}, {"Jason", "35"}, {"Mike", "55"}, {"Jessica", "99"}]

def convert(item):
    """ Convert it to a tuple instead. """
    x, y = item
    if x.isdigit():
        return y, x
    else:
        return x, y

lst = sorted(map(convert, lst), key=lambda item: item[0])

result = {}
for name, values in groupby(lst, key=lambda item: item[0]):
    marks = [int(x[1]) for x in values]
    result[name] = sum(marks) / len(marks)

print(result)

Which results in

{'Bob': 69.5, 'Jason': 35.0, 'Jessica': 99.0, 'Mike': 45.0}

But don't use sets in the first place and don't use variable names like input , dict or list .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM