def unique_generator(seq):
    """
    Remove duplicates from an iterable sequence.

    Keep a list of values we see, check to see if an item was already seen.
    Optionally preserve order.

    Does not support sets and dicts, as they are already unique.

    :param list|tuple seq: Data to yield unique values from.
    :returns type(seq): Sequence of same type of unique values of ``seq``.
    """
    def __unique_generator(seq):
        seen = set()
        seen_add = seen.add  # Speeds up, it skips __getattribute__ on seen.
        for element in seq:
            if element not in seen:
                yield element
                seen_add(element)

    if isinstance(seq, (set, dict)):
        # Should not do this, this is wasting CPU cycles.
        raise TypeError("{} types are always unique".format(type(seq)))

    return __unique_generator(seq)