From 0e0e37ab79e941f1ec01d6980c05f2f283a4d48f Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Fri, 5 Jul 2024 09:53:37 +0200 Subject: [PATCH] Add audeer.unique() --- audeer/__init__.py | 1 + audeer/core/utils.py | 23 +++++++++++++++++++++++ docs/api-src/audeer.rst | 1 + tests/test_utils.py | 24 ++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/audeer/__init__.py b/audeer/__init__.py index f56d381..f35709b 100644 --- a/audeer/__init__.py +++ b/audeer/__init__.py @@ -34,6 +34,7 @@ from audeer.core.utils import sort_versions from audeer.core.utils import to_list from audeer.core.utils import uid +from audeer.core.utils import unique from audeer.core.version import LooseVersion from audeer.core.version import StrictVersion diff --git a/audeer/core/utils.py b/audeer/core/utils.py index e4cabb4..07f8dce 100644 --- a/audeer/core/utils.py +++ b/audeer/core/utils.py @@ -829,3 +829,26 @@ def uid( uid = uid[-8:] return uid + + +def unique(sequence: typing.Sequence) -> typing.List: + r"""Unique values as list preserving original order. + + This is an alternative to ``list(set(x))``, + which returns the values in a non-deterministic order. + + Args: + sequence: sequence of values + + Returns: + unique values from ``x`` in order of appearance + + Examples: + >>> unique([2, 2, 1]) + [2, 1] + + """ + # https://stackoverflow.com/a/480227 + seen = set() + seen_add = seen.add + return [x for x in sequence if not (x in seen or seen_add(x))] diff --git a/docs/api-src/audeer.rst b/docs/api-src/audeer.rst index 6171999..aa780a2 100644 --- a/docs/api-src/audeer.rst +++ b/docs/api-src/audeer.rst @@ -44,3 +44,4 @@ audeer to_list touch uid + unique diff --git a/tests/test_utils.py b/tests/test_utils.py index c1f3b8e..0cc2c48 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -531,3 +531,27 @@ def test_uid(from_string, short): assert uid == uid2 else: assert uid != uid2 + + +@pytest.mark.parametrize( + "sequence, expected", + [ + ([], []), + ([1], [1]), + ([2, 1], [2, 1]), + ([2, 1, 2], [2, 1]), + (["a", 1, "a", 1], ["a", 1]), + ((1, 1), [1]), + ], +) +def test_unique(sequence, expected): + r"""Test audeer.unique(). + + Should return unique values in original order. + + Args: + sequence: sequence if input values + expected: expected unique list + + """ + assert audeer.unique(sequence) == expected