Skip to content

Commit 9742951

Browse files
committed
utils: Move unique_everseen helper to utils
1 parent ecf1e04 commit 9742951

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

Orange/widgets/data/owcsvimport.py

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
import typing
2828
from typing import (
29-
List, Tuple, Dict, Optional, Any, Callable, Iterable, Hashable,
29+
List, Tuple, Dict, Optional, Any, Callable, Iterable,
3030
Union, AnyStr, BinaryIO, Set
3131
)
3232

@@ -51,7 +51,9 @@
5151

5252
from Orange.widgets import widget, gui, settings
5353
from Orange.widgets.utils.concurrent import PyOwned
54-
from Orange.widgets.utils import textimport, concurrent as qconcurrent
54+
from Orange.widgets.utils import (
55+
textimport, concurrent as qconcurrent, unique_everseen
56+
)
5557
from Orange.widgets.utils.overlay import OverlayWidget
5658
from Orange.widgets.utils.settings import (
5759
QSettings_readArray, QSettings_writeArray
@@ -1033,7 +1035,7 @@ def _restoreState(self):
10331035
sitems.append(item_)
10341036

10351037
items = sitems + items
1036-
items = unique(items, key=lambda t: pathnormalize(t[0]))
1038+
items = unique_everseen(items, key=lambda t: pathnormalize(t[0]))
10371039

10381040
curr = self.recent_combo.currentIndex()
10391041
if curr != -1:
@@ -1491,32 +1493,6 @@ def index_where(iterable, pred):
14911493
return None
14921494

14931495

1494-
def unique(iterable, key=None):
1495-
# type: (Iterable[T], Optional[Callable[[T], Hashable]]) -> Iterable[T]
1496-
"""
1497-
Return an iterator over unique elements of `iterable`.
1498-
1499-
If `key` is supplied it is used as a substitute for determining
1500-
'uniqueness' of elements.
1501-
1502-
Parameters
1503-
----------
1504-
iterable : Iterable[T]
1505-
key : Callable[[T], Hashable]
1506-
1507-
Returns
1508-
-------
1509-
unique : Iterable[T]
1510-
"""
1511-
seen = set()
1512-
if key is None:
1513-
key = lambda t: t
1514-
for el in iterable:
1515-
el_k = key(el)
1516-
if el_k not in seen:
1517-
seen.add(el_k)
1518-
yield el
1519-
15201496

15211497
def samepath(p1, p2):
15221498
# type: (str, str) -> bool

Orange/widgets/utils/__init__.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import inspect
22
import sys
33
from collections import deque
4-
from typing import TypeVar, Deque, Callable, Any, Iterable
4+
from typing import TypeVar, Callable, Any, Iterable, Optional, Hashable
55

66
from AnyQt.QtCore import QObject
77

@@ -81,7 +81,6 @@ def mypredicate(x):
8181
return inspect.getmembers(obj, mypredicate)
8282

8383

84-
8584
_T1 = TypeVar("_T1")
8685

8786

@@ -90,3 +89,30 @@ def apply_all(seq, op):
9089
"""Apply `op` on all elements of `seq`."""
9190
# from itertools recipes `consume`
9291
deque(map(op, seq), maxlen=0)
92+
93+
94+
def unique_everseen(iterable, key=None):
95+
# type: (Iterable[_T1], Optional[Callable[[_T1], Hashable]]) -> Iterable[_T1]
96+
"""
97+
Return an iterator over unique elements of `iterable` preserving order.
98+
99+
If `key` is supplied it is used as a substitute for determining
100+
'uniqueness' of elements.
101+
102+
Parameters
103+
----------
104+
iterable : Iterable[T]
105+
key : Callable[[T], Hashable]
106+
107+
Returns
108+
-------
109+
unique : Iterable[T]
110+
"""
111+
seen = set()
112+
if key is None:
113+
key = lambda t: t
114+
for el in iterable:
115+
el_k = key(el)
116+
if el_k not in seen:
117+
seen.add(el_k)
118+
yield el

0 commit comments

Comments
 (0)