Then we have:
tests_dict = {'test 1': ['Manuel', 'Mariana', 'Filipa'], 'test 2': ['Manuel', 'Filipa', 'Mariana'], 'test 3': ['Mariana', 'Manuel', 'Filipa']}
You can do it like this:
1.
This first way is more didactic, so I think you understand the logic behind this:
peps_dict = {}
for test in tests_dict:
for indx, name in enumerate(tests_dict[test], 1): # vamos percorrer os nomes e respetivo indice em cada lista, começando em 1
if name not in peps_dict: # se o nome ainda nao estiver presente como chave no nosso novo dionario
peps_dict[name] = {} # vamos declara-lo como um dicionario tambem
peps_dict[name][test] = indx # ex: peps_dict['Manuel']['test 1'] = 1, {'Manuel': {'test 1': 1}}
DEMONSTRATION
2.
In this way we will import defaultdict, which in this case allows us to exclude the verification if name not in peps_dict
, this way there is no KeyError
in our new dictionary, and each key (name) by default we define to be a dictionary as well:
from collections import defaultdict
peps_dict = defaultdict(dict)
for test in tests_dict:
for indx, name in enumerate(tests_dict[test], 1):
peps_dict[name][test] = indx
DEMONSTRATION
An alternative, IN this case, to defaultdict is to use setdefault (Thanks to @Jjoao who reminded me of this in comment), and so also excuses to do the import
, this method is only applicable to dictionaries:
peps_dict = {}
for test in tests_dict:
for indx, name in enumerate(tests_dict[test], 1):
peps_dict.setdefault(name,{})[test] = indx
Demonstration
3.
This last one I did more for the challenge, the logic changes a little compared to the first one. Let’s go through all the names, join all the names in one list ((name for listN in tests_dict.values() for name in listN)
), Generator in this case, and we add each n
as being a key to our dictionary, and then via Dict compreension populate them with the corresponding values ({test: tests_dict[test].index(n) + 1}
, Let’s get the name in the original list and add 1)
peps_dict = {}
names = (name for listN in tests_dict.values() for name in listN)
for n in names:
peps_dict[n] = {test: tests_dict[test].index(n) + 1 for test in tests_dict if n in tests_dict[test]}
DEMONSTRATION
The latter may be reduced to:
names = (name for listN in tests_dict.values() for name in listN)
peps_dict = {n: {test: tests_dict[test].index(n) + 1 for test in tests_dict if n in tests_dict[test]} for n in names}
DEMONSTRATION
Output (print(peps_dict)
) for the above cases:
{'Manuel': {'test 1': 1, 'test 2': 1, 'test 3': 2}, 'Filipa': {'test 1': 3, 'test 2': 2, 'test 3': 3}, 'Mariana': {'test 1': 2, 'test 2': 3, 'test 3': 1}}
PS: This whole exercise starts from the presuposto that there are no equal names in each list, if there are two "Manuel" in a list the last to be covered will override the first, there can be no equal keys
Use indicas starting at 0. If the word is in the first position, your Dice must be "0" and not "1".
– jsbueno
Yes it is true, this is a rank system is based on the Dice but the 0 is equivalent to the first place, as I put in the desired format. I’ll fix that, sorry for the misunderstanding
– Manuel Simões
@jsbueno, I also noticed this, but I followed myself by the format I wanted, because I also thought that was what made sense in this context and by the AP explanation, "... Manuel in test 1 came first..."
– Miguel
@Miguel - of course, you have to answer what was asked. But it is worth commenting on the answer, what is the best way to leave the indexes.
– jsbueno
I agree @jsbueno, of course yes, the clearer the better
– Miguel