1from itertools import filterfalse 2 3from 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 18def 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 36