0

I'm trying to write a code in Python to create a fractional ranking list for a given one. The fraction ranking is basically the following:

We have a list of numbers x = [4,4,10,4,10,2,4,1,1,2]

First, we need to sort the list in ascending order. I will use insertion sort for it, I already coded this part.

Now we have the sorted list x = [1, 1, 2, 2, 4, 4, 4, 4, 10, 10]. The list has 10 elements and we need to compare it with a list of the first 10 natural numbers n = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

For each element in x we assign a value. Notice the number 1 appears in positions 1 and 2. So, the number 1 receives the rank (1 + 2) / 2 = 1.5.

The number 2 appears in positions 3 and 4, so it receives the rank (3 + 4) / 2 = 3.5.

The number 4 appears in positions 5, 6, 7 and 8, so it receives the rank (5 + 6 + 7 + 8) / 4 = 6.5

The number 10 appears in positions 9 and 10, so it receives the rank (9 + 10) / 2 = 9.5

In the end of this process we need to have a new list of ranks r = [1.5, 1.5, 3.5, 3.5, 6.5, 6.5, 6.5, 6.5, 9.5, 9.5]

I don't want an entire solution, I want some tips to guide me while writing down the code.

I'm trying to use the for function to make a new list using the elements in the original one, but my first attempt failed so bad. I tried to get at least the first elements right, but it didn't work as expected:

# Suppose the list is already sorted.
def ranking(x):
    l = len(x)
    for ele in range(1, l):
        t = x[ele-1]
        m = x.count(t)
        i = 0
        sum = 0
        while i < m:  # my intention was to get right at least the rank of the first item of the list
              sum = sum + 1 
              i = i + 1
        x[ele] = sum/t
    return x

Any ideais about how could I solve this problem?

  • 1
    You could try to use a hash map - `defaultdict dictionary` to store each number and its position, then loop for the ranking calculation. – Daniel Hao Feb 06 '21 at 01:36

3 Answers3

0

Ok, first, for your for loop there you can more easily loop through each element in the list by just saying for i in x:. At least for me, that would make it a little easier to read. Then, to get the rank, maybe loop through again with a nested for loop and check if it equals whatever element you're currently on. I don't know if that makes sense; I didn't want to provide too many details because you said you didn't want the full solution (definitely reply if you want me to explain better).

  • I was able to make a function that changes each value by its occurrence. For example, the list [1,1,1,2,3,3,5,6,6,6] becomes [3,3,3,1,2,2,1,3,3,3]. I wonder if I could make make the sum of subsets. For example, I have the list [1,2,3,4,5,6] and I want to sum only [3,4,5]. This will definitely solve the problem. But I don't know how to relate elements from list to list. I would appreciate more help! – Victor Paes Plinio Feb 06 '21 at 03:36
0

Here is an idea:

You can use x.count(1) to see how many number 1s you have in list, x.count(2) for number 2 etc.

Also, never use sum as a variable name since it is an inbuilt function.

Maybe use 2 for loops. First one will go through elements in list x, second one will also go through elements in list x, and if it finds the same element, appends it to new_list. You can then use something like sum(new_list) and clear list after each iteration.

You don't even need to loop through list n if you use indexing while looping through x for i, y in enumerate(x) so you could use n[i] to read the value

If you want the code I'll post it in the comment

ble
  • 287
  • 1
  • 5
  • I was able to make a code to change an element by its occurrence. The list [1,1,1,2,3,3] becomes [3,3,3,1,2,2]. I don't know how to paste code in the comments. But I followed your advice to not use sum as variable. I wonder if there is a way to make sum of subsets. If I have a list, for example, [3,2,5,8,6,9,2] how could I sum only [5,8,6]?. I still have trouble relating two lists. I would appreciate more help! – Victor Paes Plinio Feb 06 '21 at 03:46
  • `new_sum = x[2] + x[3] + x[4]` use their position in list. indexing starts at 0. so if you want third element in list, it's index would be 2 and to access that element you use x[2] – ble Feb 06 '21 at 16:31
0

@VictorPaesPlinio- would you try this sample code for the problem: (it's a partial solution, did the data aggregation work, and leave the last part put the output for your own exercise).

from collections import defaultdict

x = [4, 4, 10, 4, 10, 2, 4, 1, 1, 2]
x.sort()

print(x)

lst = list(range(1, len(x)+1))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ranking = defaultdict(list)

for idx, num in enumerate(x, 1):
    print(idx, num)
    ranking[num].append(idx)


print(ranking)
'''defaultdict(<class 'list'>, {1: [1, 2], 2: [3, 4],
                                4: [5, 6, 7, 8], 10: [9, 10]})
'''

r = []
# r = [1.5, 1.5, 3.5, 3.5, 6.5, 6.5, 6.5, 6.5, 9.5, 9.5]
#       1    1    2    2    4    4    4    4    10   10

for key, values in ranking.items():
    # key is the number, values in the list()
    print(key, values, sum(values))
    

Outputs:

1 [1, 2] 3
2 [3, 4] 7
4 [5, 6, 7, 8] 26
10 [9, 10] 19               # then you can do the final outputs part... 
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23