Home > other >  assigning scores for dictionary values
assigning scores for dictionary values

Time:01-11

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-elifs 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
  •  Tags:  
  • Related