Converting a list of "pairs" into a dictionary of dictionaries?

Viewed 191

This question was previously asked here with an egregious typo: Counting "unique pairs" of numbers into a python dictionary?

This is an algorithmic problem, and I don't know of the most efficient solution. My idea would be to somehow cache values in a list and enumerate pairs...but that would be so slow. I'm guessing there's something useful from itertools.

Let's say I have a list of integers whereby are never repeats:

list1 = [2, 3]   

In this case, there is a unique pair 2-3 and 3-2, so the dictionary should be:

{2:{3: 1}, 3:{2: 1}}

That is, there is 1 pair of 2-3 and 1 pair of 3-2.

For larger lists, the pairing is the same, e.g.

list2 = [2, 3, 4]

has the dicitonary

{2:{3:1, 4:1}, 3:{2:1, 4:1}, 4:{3:1, 2:1}}

(1) Once the size of the lists become far larger, how would one algorithmically find the "unique pairs" in this format using python data structures?

(2) I mentioned that the lists cannot have repeat integers, e.g.

[2, 2, 3]

is impossible, as there are two 2s.

However, one may have a list of lists:

list3 = [[2, 3], [2, 3, 4]] 

whereby the dictionary must be

{2:{3:2, 4:1}, 3:{2:2, 4:1}, 4:{2:1, 3:1}}

as there are two pairs of 2-3 and 3-2. How would one "update" the dictionary given multiple lists within a list?

EDIT: My ultimate use case is, I want to iterate through hundreds of lists of integers, and create a single dictionary with the "counts" of pairs. Does this make sense? There might be another data structure which is more useful.

3 Answers

For the nested list example, you can do the following, making use of itertools.permutations and dict.setdefault:

from itertools import permutations

list3 = [[2, 3], [2, 3, 4]]

d = {}
for l in list3:
    for a, b in permutations(l, 2):
        d[a][b] = d.setdefault(a, {}).setdefault(b, 0) + 1

# {2: {3: 2, 4: 1}, 3: {2: 2, 4: 1}, 4: {2: 1, 3: 1}}

For flat lists l, use only the inner loop and omit the outer one

For this example I'll just use a list with straight numbers and no nested list:

values = [3, 2, 4]
result = dict.from_keys(values)
for key, value in result.items():
    value = {}
    for num in values:
        if num != key:
            value[num] = 1

This creates a dict with each number as a key. Now in each key, make the value a nested dict who's contents are num: 1 for each number in the original values list if it isn't the name of the key that we're in

use defaultdict with permutations

from collections import defaultdict
from itertools import permutations

d = defaultdict(dict)
for i in [x for x in permutations([4,2,3])]:
    d[i[0]] = {k: 1 for k in i[1:]}

output is

In [22]: d
Out[22]: defaultdict(dict, {2: {3: 1, 4: 1}, 4: {2: 1, 3: 1}, 3: {2: 1, 4: 1}})

for inherit list of lists https://stackoverflow.com/a/52206554/8060120

Related