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]})