Home > Enterprise >  Add adjacent cross pattern cells of an array into a dictionary
Add adjacent cross pattern cells of an array into a dictionary

Time:07-25

Say I have an array:

arr =[[0, 2, 3],
      [2, 0, 4],
      [3, 4, 0]]

I would like to store in a dictionary the indices of the array as keys and the cross pattern adjacent cells as list of values. Storing the indices as keys and initialing an empty dict is straightforward:

d = defaultdict(list)

for i in range(len(arr)):
    for j in range(len(arr[0])):
        d[f'{str(i) str(j)}'] 

print(d)

defaultdict(<class 'list'>, {'00': [], '01': [], '02': [], '10': [], '11': [], '12': [], '20': [], '21': [], '22': []})

What I need is to fill up those lists with the adjacent cross pattern elements from the array. An illustration of what I mean is:

   0, 2 ,3      cross pattern; index 00 will store [2,2] the 2 on the right and below   
   2, 0, 4      cross pattern; index 11 will store [2,2,4,4]     
   3, 4, 0

Hope to be clear on what I mean, if not please let me know and I will try to re-frame the question.

CodePudding user response:

For each position, look for the 4 possibles values, that for each a condition of existance

for i in range(len(arr)):
    for j in range(len(arr[i])):
        key = f'{i}{j}'
        if i != 0:
            d[key].append(arr[i - 1][j])
        if j != 0:
            d[key].append(arr[i][j - 1])
        if i != (len(arr) - 1):
            d[key].append(arr[i   1][j])
        if j != (len(arr[i]) - 1):
            d[key].append(arr[i][j   1])
{"00": [2, 2],    "01": [0, 0, 3],    "02": [2, 4], 
 "10": [0, 3, 0], "11": [2, 2, 4, 4], "12": [3, 0, 0], 
 "20": [2, 4],    "21": [0, 3, 0],    "22": [4, 4]}

Also it is useless to use a f-string to pass one thing only,

CodePudding user response:

One approach using a dictionary comprehension:

from itertools import product

arr = [[0, 2, 3],
       [2, 0, 4],
       [3, 4, 0]]


def cross(i, j, a):
    res = []
    for ii, jj in zip([0, 1, 0, -1], [-1, 0, 1, 0]):
        ni = (i   ii)
        nj = (j   jj)
        if (-1 < ni < len(a[0])) and (-1 < nj < len(a)):
            res.append(a[nj][ni])
    return res


res = {"".join(map(str, co)): cross(co[0], co[1], arr) for co in product(range(3), repeat=2)}
print(res)

Output

{'00': [2, 2], '01': [0, 0, 3], '02': [2, 4], '10': [3, 0, 0], '11': [2, 4, 4, 2], '12': [0, 0, 3], '20': [4, 2], '21': [3, 0, 0], '22': [4, 4]}

CodePudding user response:

I modified the code a little bit because I was not sure how the defaultdict thing worked in yours but I hope this solves your problem.

arr =[[0, 2, 3],
      [2, 0, 4],
      [3, 4, 0]]

d = {'00': [], '01': [], '02': [], '10': [], '11': [], '12': [], '20': [], '21': [], '22': []}


for i in range(len(arr)):
    for j in range(len(arr[0])):
        d[f'{str(i) str(j)}'] 

print(d)

> for i in range(len(arr)):
>             for x in range(len(arr)):
>                 if i != 0:
>                     d[str(i)   str(x)].append(arr[i-1][x])
>                 if i != 2:
>                     d[str(i)   str(x)].append(arr[i 1][x])
>                 if x != 0:
>                     d[str(i)   str(x)].append(arr[i][x-1])
>                 if x != 2:
>                     d[str(i)   str(x)].append(arr[i][x 1])


print('FINAL', d)

CodePudding user response:

construct the four surrounding elements directly and exclude any values that are not in the range

from collections import defaultdict

arr, d =[[0, 2, 3], [2, 0, 4],[3, 4, 0]], defaultdict(list)

x_length, y_length = len(arr), len(arr[0])
for i in range(x_length):
    for j in range(y_length):
        items = [[x, y] for x, y in [[i-1, j], [i, j-1], [i, j 1], [i 1, j]] if x in range(x_length) and y in range(y_length)]
        d["{}{}".format(i, j)] = [arr[item[0]][item[1]] for item in items]

print(d)

# defaultdict(<class 'list'>, {'00': [2, 2], '01': [0, 3, 0], '02': [2, 4], '10': [0, 0, 3], '11': [2, 2, 4, 4], '12': [3, 0, 0], '20': [2, 4], '21': [0, 3, 0], '22': [4, 4]})

  • Related