I require some assistance with computing scores to dictionary values.
Consider the following dictionary where keys are player-id's (integers from 1,2...N) and values are lists of rankings (i.e. the distinct integers from 1,2,...,N in some permutation). Example for N=4:
player = {1: [4, 2, 1, 3], 2: [4, 3, 1, 2], 3: [4, 3, 1, 2], 4: [1, 3, 4, 2], 5: [2, 3, 4, 1], 6: [2, 1, 3, 4]
I have used the following code to assign the desired scores, y[i]
which can be seen below:
y = {}
for val in player.values():
allValues = list(val)
uniqueRank = set(allValues)
for i in uniqueRank:
z = 0
for value in player.values():
if i == value[-1]:
z = 0
elif i == value[0]:
z = 3
elif i == value[1]:
z = 2
elif i == value[2]:
z = 1
y[i] = z
print(y)
This then gives me the following scores, which are correct and what I desired:
{1: 8, 2: 8, 3: 9, 4: 11}
However, I want to simplify this code, automate the assignment of values to z instead of the if..elif
clauses:
elif i == value[1]:
z = 2
for example.
EDIT: The component for
for val in player.values():
allValues = list(val)
uniqueRank = set(allValues)
simply grabs the unique values from the dictionary above, so in this regard it simply collects 1-4, which is what the players are denoted by.
CodePudding user response:
You can write the second loop a bit concisely if you replace
if i == value[-1]:
z = 0
elif i == value[0]:
z = 3
elif i == value[1]:
z = 2
elif i == value[2]:
z = 1
with
for j, val in enumerate(value):
if val == i:
z = 3-j
The whole code as a dict comprehension:
y = {i: sum((3-j for value in player.values() for j, val in enumerate(value) if val == i)) for i in set([v for value in player.values() for v in value])}
Output:
{1: 8, 2: 8, 3: 9, 4: 11}
CodePudding user response:
One thing that which you can notice is the sum of the value with which you're incrementing z
and the index of i
add up to 3. Thus instead of if-elif
s you can just subtract the index of i
in value and add it to z
.
Also, I noticed that the 1st for
loop which sets the range
only assigns the last value in the player dictionary, but still it ran correct since only the 4 values (1,2,3,4) were being repeated, thus I slightly modified the code a little bit, like this...
player = {1: [4, 2, 1, 3], 2: [4, 3, 1, 2], 3: [4, 3, 1, 2], 4: [1, 3, 4, 2], 5: [2, 3, 4, 1], 6: [2, 1, 3, 4]}
y, setAllValues = {}, set([val for lstval in player.values() for val in lstval])
for i in setAllValues:
z = 0
for value in player.values():
z = (3 - value.index(i))
y[i] = z
print(y)
Output:-
{1: 8, 2: 8, 3: 9, 4: 11}
Executed in 4.9591064453125e-05 seconds