In [1]: def my_relation(x): ...: return x % 3 ...: In [2]: from collections import defaultdict In [3]: def partition(X, relation): ...: d = defaultdict(list) ...: for item in X: ...: d[my_relation(item)].append(item) ...: return d.values() ...: In [4]: X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] In [5]: partition(X, my_relation) Out[5]: [[3, 6, 9, 12], [1, 4, 7, 10], [2, 5, 8, 11]]
For binary function:
from collections import defaultdict from itertools import combinations def partition_binary(Y, relation): d = defaultdict(list) for (a, b) in combinations(Y): l = d[my_relation(a, b)] l.append(a) l.append(b) return d.values()
You can do something like this:
partition_binary(partition(X, rank), my_relation)
Oh, that obviously doesn't work if my_relation returns a boolean. I would say, I came up with some abstract way to represent each isomorphism, although I suspect that the goal is to try to do this in the first place.