Creating a binary nested square dict from a list

Viewed 61

Starting from a list like this:

list = ["1-5", "1-6", "2-5", "2-6", "2-7", "2-8", "3-6", "3-7", "3-8", "4-1"]

I need to get this dict:

dict = {
    "1-5": {"1-5": 1, "1-6":1, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "1-6": {"1-5": 1, "1-6":1, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "2-5": {"1-5": 0, "1-6":0, "2-5":1, "2-6":1, "2-7":1, "2-8":1, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "2-6": {"1-5": 0, "1-6":0, "2-5":1, "2-6":1, "2-7":1, "2-8":1, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "2-7": {"1-5": 0, "1-6":0, "2-5":1, "2-6":1, "2-7":1, "2-8":1, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "2-8": {"1-5": 0, "1-6":0, "2-5":1, "2-6":1, "2-7":1, "2-8":1, "3-6":0, "3-7":0, "3-8":0, "4-1":0},
    "3-6": {"1-5": 0, "1-6":0, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":1, "3-7":1, "3-8":1, "4-1":0},
    "3-7": {"1-5": 0, "1-6":0, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":1, "3-7":1, "3-8":1, "4-1":0},
    "3-8": {"1-5": 0, "1-6":0, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":1, "3-7":1, "3-8":1, "4-1":0},
    "4-1": {"1-5": 0, "1-6":0, "2-5":0, "2-6":0, "2-7":0, "2-8":0, "3-6":0, "3-7":0, "3-8":0, "4-1":1}
}

Basically the two dimensions are the same list. It's a square matrix and the binary values are based on the following condition:

If right(i,1) = right(j,1):
    dict[i][j] = 1
    else
    dict[i][j] = 0 

If the indexes i,j of the element dict[i][j] start with the same number (could be more than one, ex. "11-5") then dict[i][j] = 1, else dict[i][j] = 0

How can i write this in python?

4 Answers

You can write nested dict comprehension to achieve this as:

my_list = ["1-5", "1-6", "2-5", "2-6", "2-7", "2-8", "3-6", "3-7", "3-8", "4-1"]

my_dict = {s: {d: int(d.split('-')[0] == s.split('-')[0]) for d in my_list} for s in my_list}

where my_dict will hold:

{
    '1-5': {'1-5': 1, '1-6': 1, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0}, 
    '1-6': {'1-5': 1, '1-6': 1, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0}, 
    '2-5': {'1-5': 0, '1-6': 0, '2-5': 1, '2-6': 1, '2-7': 1, '2-8': 1, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0}, 
    '2-6': {'1-5': 0, '1-6': 0, '2-5': 1, '2-6': 1, '2-7': 1, '2-8': 1, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0}, 
    '2-7': {'1-5': 0, '1-6': 0, '2-5': 1, '2-6': 1, '2-7': 1, '2-8': 1, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0},
    '2-8': {'1-5': 0, '1-6': 0, '2-5': 1, '2-6': 1, '2-7': 1, '2-8': 1, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 0},
    '3-6': {'1-5': 0, '1-6': 0, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 1, '3-7': 1, '3-8': 1, '4-1': 0},
    '3-7': {'1-5': 0, '1-6': 0, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 1, '3-7': 1, '3-8': 1, '4-1': 0},
    '3-8': {'1-5': 0, '1-6': 0, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 1, '3-7': 1, '3-8': 1, '4-1': 0},
    '4-1': {'1-5': 0, '1-6': 0, '2-5': 0, '2-6': 0, '2-7': 0, '2-8': 0, '3-6': 0, '3-7': 0, '3-8': 0, '4-1': 1}
}

You can try like this:

list1 = ["1-5", "1-6", "2-5", "2-6", "2-7", "2-8", "3-6", "3-7", "3-8", "4-1"]
d={}
for element in list1:
    start=element.split('-')[0]
    d1={}
    for ele in list1:
        if ele.split('-')[0]==start:
            d1[ele]=1
        else:
            d1[ele]=0
    d[element]=d1
print(d)

I wrote a similar solution to Moinuddin Quadri's with a slight variation to avoid having to split and retrieve the first number on each loop of the inner comprehension.

I tested both with %%timeit in a Jupyter notebook with the following results:

Other answer: 44 µs ± 3.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

This answer: 33.3 µs ± 3.58 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

keys = ["1-5", "1-6", "2-5", "2-6", "2-7", "2-8", "3-6", "3-7", "3-8", "4-1"]
result = {
    outer_key: {inner_key: int(inner_key.startswith(first_int)) for inner_key in keys}
    for first_int, outer_key in zip((key.split("-")[0] for key in keys), keys)
}
print(result)
# output
{
  "1-5": {
    "1-5": 1,
    "1-6": 1,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "1-6": {
    "1-5": 1,
    "1-6": 1,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "2-5": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 1,
    "2-6": 1,
    "2-7": 1,
    "2-8": 1,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "2-6": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 1,
    "2-6": 1,
    "2-7": 1,
    "2-8": 1,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "2-7": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 1,
    "2-6": 1,
    "2-7": 1,
    "2-8": 1,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "2-8": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 1,
    "2-6": 1,
    "2-7": 1,
    "2-8": 1,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 0
  },
  "3-6": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 1,
    "3-7": 1,
    "3-8": 1,
    "4-1": 0
  },
  "3-7": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 1,
    "3-7": 1,
    "3-8": 1,
    "4-1": 0
  },
  "3-8": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 1,
    "3-7": 1,
    "3-8": 1,
    "4-1": 0
  },
  "4-1": {
    "1-5": 0,
    "1-6": 0,
    "2-5": 0,
    "2-6": 0,
    "2-7": 0,
    "2-8": 0,
    "3-6": 0,
    "3-7": 0,
    "3-8": 0,
    "4-1": 1
  }
}

First, use list comprehension to find the indexes from the list. Then use nested dict comprehension.

ss = ["1-5", "1-6", "2-5", "2-6", "2-7", "2-8", "3-6", "3-7", "3-8", "4-1"]

indexes = [list(map(int, item.split('-'))) for item in ss]
output = {
    f'{x1}-{y1}' : 
        { f'{x2}-{y2}' : (1 if x2==x1 else 0) for x2,y2 in indexes}
    for x1,y1 in indexes
}
Related