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