code: def unique_everseen(iterable, key=None):
      
      seenset = set()
      seenset_add = seenset.add
      seenlist = []
      seenlist_add = seenlist.append
      if key is None:
          for element in iterable:
              try:
                  if element not in seenset:
                      seenset_add(element)
                      yield element
              except TypeError:
                  if element not in seenlist:
                      seenlist_add(element)
                      yield element
      else:
          for element in iterable:
              k = key(element)
              try:
                  if k not in seenset:
                      seenset_add(k)
                      yield element
              except TypeError:
                  if k not in seenlist:
                      seenlist_add(k)
                      yield element
docs: Yield unique elements, preserving order.
  
          >>> list(unique_everseen('AAAABBBCCDAABBB'))
          ['A', 'B', 'C', 'D']
          >>> list(unique_everseen('ABBCcAD', str.lower))
          ['A', 'B', 'C', 'D']
  
      Sequences with a mix of hashable and unhashable items can be used.
      The function will be slower (i.e., `O(n^2)`) for unhashable items.
  
      Remember that ``list`` objects are unhashable - you can use the *key*
      parameter to transform the list to a tuple (which is hashable) to
      avoid a slowdown.
  
          >>> iterable = ([1, 2], [2, 3], [1, 2])
          >>> list(unique_everseen(iterable))  # Slow
          [[1, 2], [2, 3]]
          >>> list(unique_everseen(iterable, key=tuple))  # Faster
          [[1, 2], [2, 3]]
  
      Similary, you may want to convert unhashable ``set`` objects with
      ``key=frozenset``. For ``dict`` objects,
      ``key=lambda x: frozenset(x.items())`` can be used.