Some things only/obviously make sense over pairs of items. For those, go with a literal 2
for x,y in itertools.combinations(obj, 2):
if is_overlapping(x,y):
raise OverlapError(x,y)
However, sometimes the subset’s size just happens to be two (but you might change it), maybe a constant would be good. Ditto if you’re doing some math where there are “real” 2s that are part of a formula and incidental ones that are due to the subset size. For example:
subset_size = 2
for subset in itertools.combinations(X, subset_size):
mse.append(sum((subset - target)**2)/subset_size)
is a bit more flexible and more clear than using all 2s, IMO, and at very little cost (YAGNI blah blah, but I think that’s an argument for not making a whole configuration system that lets you set the size at runtime).
Only in my choice of variable name. OP drew a line at 0, 1 and -1. What I did there was highlight that the implications of that rule are absurd. See how your sum of squares also contains a 2? VERBOTEN!!!! And don't you dare re-use "subset_size" ;)
This is somewhat akin to Dijkstra's opinion on goto. Which is actually great advice when you're doing apps in javascript, but doesn't get you very far if you're writing or generating assembly. When such advice is promoted to a taboo, I side with Churchill: this is the type of arrant pedantry up with which I will not put. Or Emerson: foolish consistency is the hobgoblin of little minds.
Yes, too many numeric literals can make code hard to read. But math is hard to read[1] because you need to really think about it -- you can't avoid the complexity; you can only rearrange it. Where you put it is a matter of taste, and absolutes have absurd consequences.
As for the original notion of indexing a triangular array, I have a greater concern:
for i in range(n):
for j in range(i):
foo(array[i][j])
this is self-documenting in the sense that I immediately know the relationship between i and j -- without reading documentation, I can't recall if itertools.combinations will give me the upper or lower triangle. In this case, I'd avoid the 2 for entirely different reasons :)
[1] and I don't mean "let's go shopping!" -- I mean that reading a math paper, even for experts, can take days per page.