Finding the best terms to use
You have a bug, if you remove an item in your for loop without breaking you get an IndexError.
Instead use a worse set so that you know what to skip.
What you seem to be doing is performing a sort, and so if you make a cmp function you can use sorted.
To do this you need to use functools.cmp_to_key and then you can itertools.takewhile.


And so I'd use:

import functools
import itertools
from typing import Set, List


class Term(int):
    def is_better_than(self, other):
        return self // 2 &gt; other // 2


def cmp(self: Term, other: Term):
    if self.is_better_than(other):
        return 1
    if other.is_better_than(self):
        return -1
    return 0


def get_best_terms(terms: Set[Term]) -&gt; List[Term]:
    if not terms:
        return []
    terms = sorted(terms, key=functools.cmp_to_key(cmp), reverse=True)
    best = terms[0]
    return list(itertools.takewhile(lambda i: not best.is_better_than(i), terms))


print(get_best_terms(map(Term, [1, 2, 3, 4, 5])))
print(get_best_terms(map(Term, [1, 2, 3, 4])))
print(get_best_terms(map(Term, [5, 1, 2, 4, 3])))
print(get_best_terms(map(Term, [5, 1, 4, 3])))


This can however be simplified if Terms are comparable, as you won't need to use key and can remove the need for a lambda.

@functools.total_ordering
class Term(int):
    def __gt__(self, other: Term) -&gt; bool:
        return self // 2 &gt; other // 2

    def __eq__(self, other: Term) -&gt; bool:
        return self // 2 == other // 2


def get_best_terms(terms: Set[Term]) -&gt; List[Term]:
    if not terms:
        return []
    terms = sorted(terms, reverse=True)
    return list(itertools.takewhile(terms[0].__eq__, terms))