def uniq(iterable, key=lambda x: x):
    """
    Remove duplicates from an iterable. Preserves order.
    :type iterable: Iterable[Ord => A]
    :param iterable: an iterable of objects of any orderable type
    :type key: Callable[A] -> (Ord => B)
    :param key: optional argument; by default an item (A) is discarded
    if another item (B), such that A == B, has already been encountered and taken.
    If you provide a key, this condition changes to key(A) == key(B); the callable
    must return orderable objects.
    """
    keys = set()
    res = []
    for x in iterable:
        k = key(x)
        if k in keys:
            continue
        res.append(x)
        keys.add(k)
    return res
