| 48 | |
| 49 | @cython.ccall |
| 50 | def unique_list(seq: Iterable[_T]) -> List[_T]: |
| 51 | # this version seems somewhat faster for smaller sizes, but it's |
| 52 | # significantly slower on larger sizes |
| 53 | # w = {x:None for x in seq} |
| 54 | # return PyDict_Keys(w) if cython.compiled else list(w) |
| 55 | if cython.compiled: |
| 56 | seen: Set[_T] = set() |
| 57 | return [x for x in seq if x not in seen and not set.add(seen, x)] |
| 58 | else: |
| 59 | return list(dict.fromkeys(seq)) |
| 60 | |
| 61 | # In case passing an hashfunc is required in the future two version were |
| 62 | # tested: |
| 63 | # - this version is faster but returns the *last* element matching the |
| 64 | # hash. |
| 65 | # from cython.cimports.cpython.dict import PyDict_Values |
| 66 | # w: dict = {hashfunc(x): x for x in seq} |
| 67 | # return PyDict_Values(w) if cython.compiled else list(w.values()) |
| 68 | # - this version is slower but returns the *first* element matching the |
| 69 | # hash. |
| 70 | # seen: set = set() |
| 71 | # res: list = [] |
| 72 | # for x in seq: |
| 73 | # h = hashfunc(x) |
| 74 | # if h not in seen: |
| 75 | # res.append(x) |
| 76 | # seen.add(h) |
| 77 | # return res |
| 78 | |
| 79 | |
| 80 | @cython.cclass |