简体   繁体   中英

Recursively find adjacent coordinates for n-dimensional array

For any tuple of coordinates I am given (ex. (2,2) or (1,2,3) or (4,5,6,7,8), etc.), how can I get a list of all the adjacent coordinates.
So that,

find_adjacents((2,2))    

  >>[[1,1],[1,2],[1,3],[2,1],[2,3],[3,1],[3,2],[3,3]]  

and

find_adjacents((2,2,2,2))

would return something with 3^4-1 elements

You can ignore edge cases for this (imagine indices range from -inf to inf)

You can use itertools.product for this. The Cartesian product of the ranges will include the input itself, so we need to remove it afterwards. list.pop works for this, because the product is generated in order, such that the input itself will always be exactly the middle element.

from itertools import product

def neighbours(t):
    ranges = [(x-1, x, x+1) for x in t]
    result = list(product(*ranges))
    result.pop(len(result) // 2)
    return result

Examples (formatted for readability):

>>> neighbours( (1, 2) )
[(0, 1), (0, 2), (0, 3),
 (1, 1),         (1, 3),
 (2, 1), (2, 2), (2, 3)]

>>> neighbours( (1, 1, 1) )
[(0, 0, 0), (0, 0, 1), (0, 0, 2),
 (0, 1, 0), (0, 1, 1), (0, 1, 2),
 (0, 2, 0), (0, 2, 1), (0, 2, 2),

 (1, 0, 0), (1, 0, 1), (1, 0, 2),
 (1, 1, 0),            (1, 1, 2),
 (1, 2, 0), (1, 2, 1), (1, 2, 2),

 (2, 0, 0), (2, 0, 1), (2, 0, 2),
 (2, 1, 0), (2, 1, 1), (2, 1, 2),
 (2, 2, 0), (2, 2, 1), (2, 2, 2)]

You can use recursion:

def combos(d, c = []):
  if not d:
     yield c
  else:
     yield from [i for b in range(d[0]-1, d[0]+2) for i in combos(d[1:], c+[b])]

vals = (2,2)
print(list(combos(vals)))
print(list(combos((1, 1, 1))))

Output:

[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0], [2, 2, 1], [2, 2, 2]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM