Sort nested dictionaries and replace dictioary values with ordered numbers
<p>Not sure if my problem sound a bit tricky..my requirement is like this: I have three columns of data in txt file as below:</p>

<pre><code>col1,col2,col3/n
11,0.95,21/n
11,0.75,22/n
11,0.85,23/n
11,0.65,24/n
12,0.63,22/n
12,0.75,24/n
12,0.45,25/n
...
</code></pre>

<p>col1 can be viewed as dict keys which repeat for &lt;= 5 times, col3 can also viewed as nested dict keys with values in col2, i.e. each key in col1 has &lt;= 5 pairs of (col2: col3). </p>

<p>I would like to sort the nested dictionary by col2 and replace the col2 values with highest ranking, i.e.: I don't care about the values in col2, i only care about the ranking of col3 for each col1 value:</p>

<pre><code>col1,col2,col3
11,1,21/n
11,2,23/n
11,3,22/n
11,4,24/n
12,1,24/n
12,2,22/n
12,3,25/n
...
</code></pre>

<p>I tried turning the data into nested dictionaries like: </p>

<pre><code>{col1:{col3:col2}}
{11:{21:0.95,22:0.75,23:0.85,24:0.65},12:{22:0.63,24:0.75,25:0.45}}
</code></pre>

<p>I have searched around and found some solutions like sort nested dict etc., but I cannot replace the values with rankings either...can someone please help?</p>

<p>Well, here is a way to do it in basic Python:</p>

<pre><code>In [90]: col1
Out[90]: [11, 11, 11, 11, 12, 12, 12]

In [91]: col2
Out[91]: [0.95, 0.75, 0.85, 0.65, 0.63, 0.75, 0.45]

In [92]: col3
Out[92]: [21, 22, 23, 24, 22, 24, 25]
</code></pre>

<p>Let's create <code>data</code> consisting of items from each columns:</p>

<p>In [163]: data = [*zip(col1, col2, col3)]</p>

<pre><code>In [164]: data
Out[164]: 
[(11, 0.95, 21),
 (11, 0.75, 22),
 (11, 0.85, 23),
 (11, 0.65, 24),
 (12, 0.63, 22),
 (12, 0.75, 24),
 (12, 0.45, 25)]
</code></pre>

<p>Let's use <code>itertools</code> module to group them up:</p>

<pre><code>In [174]: import itertools

In [175]: groups = itertools.groupby(data, key=lambda x: x[0])
</code></pre>

<p>Now, <code>groups</code> is a generator. If we want to see what it looks like<br>
we will need to iterate it:</p>

<pre><code>for a, b, in groups:
    print(a, list(b))
</code></pre>

<p>and we get:</p>

<pre><code>11 [(11, 0.95, 21), (11, 0.75, 22), (11, 0.85, 23), (11, 0.65, 24)]
12 [(12, 0.63, 22), (12, 0.75, 24), (12, 0.45, 25)]
</code></pre>

<p>But we exhausted the iterator. So let's create it again, and now <br>
that we know what it contains, we can perform the desired sorting:</p>

<pre><code>In [177]: groups = itertools.groupby(data, key=lambda x: x[0])

In [178]: groups2 = [sorted(list(b), reverse=True) for a, b in groups]

In [179]: groups2
Out[179]: 
[[(11, 0.95, 21), (11, 0.85, 23), (11, 0.75, 22), (11, 0.65, 24)],
 [(12, 0.75, 24), (12, 0.63, 22), (12, 0.45, 25)]]
</code></pre>

<p>OK, one more thing, and I do that now in the editor:</p>

<pre><code>for i in range(len(groups2)):
    groups2[i] = [(x, i, z) for i, (x, y, z) in enumerate(groups2[i], 1)]

for g in groups2:
    for item in g:
        print(item)
</code></pre>

<p>And we get:</p>

<pre><code>(11, 1, 21)
(11, 2, 23)
(11, 3, 22)
(11, 4, 24)
(12, 1, 24)
(12, 2, 22)
(12, 3, 25)
</code></pre>

python sorting dictionary