You can use a dict to group the data to see where/if any comb lands in the original list zipping up pairs:
it1, it2 = iter(Data), iter(Data)
next(it2)
Combinations = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
d = {c: [] for c in Combinations}
ind = 2
for i, j in zip(it1, it2):
if (i, j) in d and ind < len(Data):
d[(i, j)].append(Data[ind])
ind += 1
print(d)
Which would give you:
{(0, 1): [2, 2], (1, 2): [1, 0], (0, 0): [], (2, 1): [0, 1], (1, 1): [2], (2, 0): [1, 2, 1, 2], (2, 2): [], (1, 0): [2], (0, 2): [0, 0, 0, 1]}
You could also do it in reverse:
from collections import defaultdict
it1, it2 = iter(Data), iter(Data)
next(it2)
next_ele_dict = defaultdict(list)
data_iter = iter(Data[2:])
for ind, (i, j) in enumerate(zip(it1, it2)):
if ind < len(Data) -2:
next_ele_dict[(i, j)].append(next(data_iter))
def next_ele():
for comb in set(Combinations):
if comb in next_ele_dict:
yield comb, next_ele_dict[comb]
print(list(next_ele()))
Which would give you:
[((0, 1), [2, 2]), ((1, 2), [1, 0]), ((2, 1), [0, 1]), ((1, 1), [2]), ((2, 0), [1, 2, 1, 2]), ((1, 0), [2]), ((0, 2), [0, 0, 0, 1])]
Any approach is better than a pass over the Data list for every element in Combinations.
To work for arbitrary length tuples we just need to create the tuples based on the length:
from collections import defaultdict
n = 2
next_ele_dict = defaultdict(list)
def chunks(iterable, n):
for i in range(len(iterable)-n):
yield tuple(iterable[i:i+n])
data_iter = iter(Data[n:])
for tup in chunks(Data, n):
next_ele_dict[tup].append(next(data_iter))
def next_ele():
for comb in set(Combinations):
if comb in next_ele_dict:
yield comb, next_ele_dict[comb]
print(list(next_ele()))
You can apply it to whatever implementation you prefer, the logic will be the same as far as making the tuples goes.