def uniquify(seq, preserve_order=False):
    """Return sequence with duplicate items in sequence seq removed.

    The code is based on usenet post by Tim Peters.

    This code is O(N) if the sequence items are hashable, O(N**2) if not.
    
    Peter Bengtsson has a blog post with an empirical comparison of other
    approaches:
    http://www.peterbe.com/plog/uniqifiers-benchmark

    If order is not important and the sequence items are hashable then
    list(set(seq)) is readable and efficient.

    If order is important and the sequence items are hashable generator
    expressions can be used (in py >= 2.4) (useful for large sequences):
    seen = set()
    do_something(x for x in seq if x not in seen or seen.add(x))

    Arguments:
    seq -- sequence
    preserve_order -- if not set the order will be arbitrary
                      Using this option will incur a speed penalty.
                      (default: False)

    Example showing order preservation:

    >>> uniquify(['a', 'aa', 'b', 'b', 'ccc', 'ccc', 'd'], preserve_order=True)
    ['a', 'aa', 'b', 'ccc', 'd']

    Example using a sequence of un-hashable items:

    >>> uniquify([['z'], ['x'], ['y'], ['z']], preserve_order=True)
    [['z'], ['x'], ['y']]

    The sorted output or the non-order-preserving approach should equal
    that of the sorted order-preserving approach output:
    
    >>> unordered = uniquify([3, 3, 1, 2], preserve_order=False)
    >>> unordered.sort()
    >>> ordered = uniquify([3, 3, 1, 2], preserve_order=True)
    >>> ordered.sort()
    >>> ordered
    [1, 2, 3]
    >>> int(ordered == unordered)
    1

    """
    try:
        # Attempt fast algorithm.
        d = {}
        if preserve_order:
            # This is based on Dave Kirby's method (f8) noted in the post:
            # http://www.peterbe.com/plog/uniqifiers-benchmark
            return [x for x in seq if (x not in d) and not d.__setitem__(x, 0)]
        else:
            for x in seq:
                d[x] = 0
            return d.keys()
    except TypeError:
        # Have an unhashable object, so use slow algorithm.
        result = []
        app = result.append
        for x in seq:
            if x not in result:
                app(x)
        return result