Adding a sorted tuple to a dictionary as a key
<p>I am very new to Python and i am trying my best to learn Python. I have been trying to implement a community detection algorithm that i came across and i would really appreciate if i could get help from anyone here.  </p>

<p>I have a <strong>defaultdict(list)</strong>, my input, which looks like :  </p>

<pre><code>input = [('B', ['D']), ('D', ['E']), ('F', ['E']), ('G', ['D', 'F'])]
</code></pre>

<p>Here, <strong>'B', 'D', 'E'</strong> etc represent nodes in a tree. The <strong>key</strong> in the dictionary represents <strong>children</strong> nodes and the <strong>value</strong> represents <strong>parent</strong> nodes. So in the above input, 'B' is a child of 'D', 'D' is a child of 'E' etc.</p>

<p>I am trying to create a dictionary with <strong>tuples</strong>(in sorted order) as <strong>keys</strong> and <strong>int</strong> as <strong>values</strong>. The expected output is:  </p>

<pre><code>output = [(('A', 'B'), 1.0), (('B', 'C'), 1.0), (('B', 'D'), 3.0), (('D', 'E'), 4.5), (('D', 'G'), 0.5), (('E', 'F'), 1.5), (('F', 'G'), 0.5)]
</code></pre>

<p>In the above output, the key is a tuple which represents an edge in the input. For ex : ('A' , 'B') represents an edge between A and B and the int value is something that i calculate.</p>

<p>I would love to know know how this can be done.</p>

<p>I have tried the following:</p>

<p>1)</p>

<pre><code>edges = []
for node,parents in input.items():
    for p in sorted(parents):
        tup = (node,p)
        tup = sorted(tup)
        edges.append(tup)
/*output of the above line: [['E', 'F'], ['D', 'E'], ['A', 'B'], ['B', 'C'], ['B', 'D'], ['D', 'G'], ['F', 'G']]*/
</code></pre>

<p>And then i thought i will pull values from this list to a dict.  Obviously, i got a dict with <strong>key</strong> of type <strong>List</strong> and further the items in list were not sorted.</p>

<p>2) </p>

<pre><code>edges = {}

for node,parents in node2parents.items():
    for p in sorted(parents):
        t = (node,p)
        t = sorted(t)
        edges[t] = 0
</code></pre>

<p>On executing the above, i got a <strong>TypeError: unhashable type: 'list'</strong></p>

<p>I have tried few other ways, but none proved to be successful. It would be great if someone could help me learn how i could do this.</p>

<p>PS : I would have posted evidences of more "failed" efforts of mine, but i dint want to waste your time by making you go through all the stupid ways i have been trying to accomplish my goals. Also, i googled and tried if i could find an answer to my question. Though there were countless possible solutions, i still failed to implement the logic successfully. I am honestly trying to learn Python and it would be great if you could push me in the right direction.</p>

<p><a href="https://docs.python.org/3/library/functions.html#sorted" rel="nofollow"><code>sorted</code> returns a new sorted <code>list</code></a>, regardless of the input's type. If you want the result to be a sorted <code>tuple</code>, just wrap the <code>sorted</code> call in the <code>tuple</code> constructor:</p>

<pre><code>t = tuple(sorted(t))
</code></pre>

<p>For Python built-in types, only immutable types (e.g. <code>int</code>, <code>str</code>, or <code>tuple</code>s and <code>frozenset</code>s containing only other immutable types) are suitable for use as keys in <code>dict</code>s and values in <code>set</code>/<code>frozenset</code>s, which is why preserving the <code>tuple</code> type is important; <code>list</code> is mutable, and to avoid a sticky situation where a mutable object like a <code>list</code> is added to a <code>dict</code>, then changed (so suddenly the hash and equality comparisons for it don't correspond to where it was bucketed), rendering it unfindable and violating the <code>dict</code> assumptions, they prohibit using mutable built-in types completely.</p>

python dictionary tuples defaultdict