1  from itertools import filterfalse
       2  
       3  from typing import (
       4      Callable,
       5      Iterable,
       6      Iterator,
       7      Optional,
       8      Set,
       9      TypeVar,
      10      Union,
      11  )
      12  
      13  # Type and type variable definitions
      14  _T = TypeVar('_T')
      15  _U = TypeVar('_U')
      16  
      17  
      18  def unique_everseen(
      19      iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = None
      20  ) -> Iterator[_T]:
      21      "List unique elements, preserving order. Remember all elements ever seen."
      22      # unique_everseen('AAAABBBCCDAABBB') --> A B C D
      23      # unique_everseen('ABBCcAD', str.lower) --> A B C D
      24      seen: Set[Union[_T, _U]] = set()
      25      seen_add = seen.add
      26      if key is None:
      27          for element in filterfalse(seen.__contains__, iterable):
      28              seen_add(element)
      29              yield element
      30      else:
      31          for element in iterable:
      32              k = key(element)
      33              if k not in seen:
      34                  seen_add(k)
      35                  yield element