Skip to content
Snippets Groups Projects
Commit b8817fe3 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

added AlreadySeen

parent 4286c8d3
No related branches found
No related tags found
No related merge requests found
# v2.14.35 # v2.14.35
* added AlreadySeen
...@@ -54,6 +54,13 @@ elements matching the callable. If there are, raises ValueError. ...@@ -54,6 +54,13 @@ elements matching the callable. If there are, raises ValueError.
.. autofunction:: satella.coding.sequences.choose_one .. autofunction:: satella.coding.sequences.choose_one
AlreadySeen
-----------
.. autoclass:: satella.coding.sequences.AlreadySeen
:members:
filter_out_nones filter_out_nones
---------------- ----------------
......
__version__ = '2.14.35a1' __version__ = '2.14.35a2'
...@@ -4,7 +4,7 @@ from .iterators import infinite_counter, take_n, is_instance, skip_first, zip_sh ...@@ -4,7 +4,7 @@ from .iterators import infinite_counter, take_n, is_instance, skip_first, zip_sh
stop_after, iter_dict_of_list, shift, other_sequence_no_longer_than, count, even, \ stop_after, iter_dict_of_list, shift, other_sequence_no_longer_than, count, even, \
odd, n_th, smart_enumerate, smart_zip, unique, ConstruableIterator, walk, length, map_list, \ odd, n_th, smart_enumerate, smart_zip, unique, ConstruableIterator, walk, length, map_list, \
is_empty, IteratorListAdapter, enumerate2, to_iterator, ListWrapperIterator, try_close, \ is_empty, IteratorListAdapter, enumerate2, to_iterator, ListWrapperIterator, try_close, \
f_range, iterate_callable f_range, iterate_callable, AlreadySeen
from .sequences import is_last, add_next, half_cartesian, group_quantity, Multirun, make_list, \ from .sequences import is_last, add_next, half_cartesian, group_quantity, Multirun, make_list, \
infinite_iterator, filter_out_false, filter_out_nones, index_of, index_of_max infinite_iterator, filter_out_false, filter_out_nones, index_of, index_of_max
...@@ -16,4 +16,4 @@ __all__ = ['choose', 'choose_one', 'infinite_counter', 'take_n', 'is_instance', ...@@ -16,4 +16,4 @@ __all__ = ['choose', 'choose_one', 'infinite_counter', 'take_n', 'is_instance',
'make_list', 'RollingArithmeticAverage', 'index_of', 'index_of_max', 'make_list', 'RollingArithmeticAverage', 'index_of', 'index_of_max',
'IteratorListAdapter', 'enumerate2', 'infinite_iterator', 'to_iterator', 'IteratorListAdapter', 'enumerate2', 'infinite_iterator', 'to_iterator',
'filter_out_false', 'filter_out_nones', 'ListWrapperIterator', 'try_close', 'filter_out_false', 'filter_out_nones', 'ListWrapperIterator', 'try_close',
'f_range', 'iterate_callable'] 'f_range', 'iterate_callable', 'AlreadySeen']
...@@ -5,7 +5,7 @@ import warnings ...@@ -5,7 +5,7 @@ import warnings
from ..decorators import for_argument, wraps from ..decorators import for_argument, wraps
from ..recast_exceptions import rethrow_as, silence_excs from ..recast_exceptions import rethrow_as, silence_excs
from ..typing import Iteratable, T, U, Predicate, V from ..typing import Iteratable, T, U, Predicate, V, K
def iterate_callable(clbl: tp.Callable[[int], V], start_from: int = 0, def iterate_callable(clbl: tp.Callable[[int], V], start_from: int = 0,
...@@ -183,6 +183,30 @@ class ConstruableIterator: ...@@ -183,6 +183,30 @@ class ConstruableIterator:
return len(self.entries) return len(self.entries)
class AlreadySeen(tp.Generic[K]):
"""
Class to filter out unique objects
"""
__slots__ = ('set',)
def __init__(self):
self.set = set()
def is_unique(self, key: K) -> bool:
"""
Has the element been spotted first time?
Add it to the set.
:param key: element to check
:return: whether the element was seen for the first time
"""
try:
return key not in self.set
finally:
self.set.add(key)
def unique(lst: Iteratable) -> tp.Iterator[T]: def unique(lst: Iteratable) -> tp.Iterator[T]:
""" """
Return each element from lst, but return every element only once. Return each element from lst, but return every element only once.
......
...@@ -6,12 +6,17 @@ from satella.coding.sequences import choose, choose_one, infinite_counter, take_ ...@@ -6,12 +6,17 @@ from satella.coding.sequences import choose, choose_one, infinite_counter, take_
iter_dict_of_list, shift, other_sequence_no_longer_than, count, even, odd, Multirun, n_th, \ iter_dict_of_list, shift, other_sequence_no_longer_than, count, even, odd, Multirun, n_th, \
unique, length, map_list, smart_zip, is_empty, make_list, RollingArithmeticAverage, \ unique, length, map_list, smart_zip, is_empty, make_list, RollingArithmeticAverage, \
enumerate2, infinite_iterator, to_iterator, filter_out_false, filter_out_nones, \ enumerate2, infinite_iterator, to_iterator, filter_out_false, filter_out_nones, \
index_of, index_of_max, try_close, f_range, iterate_callable index_of, index_of_max, try_close, f_range, iterate_callable, AlreadySeen
from satella.coding.predicates import x from satella.coding.predicates import x
class TestSequences(unittest.TestCase): class TestSequences(unittest.TestCase):
def test_already_seen(self):
as_ = AlreadySeen()
self.assertTrue(as_.is_unique(1))
self.assertFalse(as_.is_unique(1))
def test_iterate_callable(self): def test_iterate_callable(self):
a = [1, 2, 3] a = [1, 2, 3]
b = lambda i: a[i] b = lambda i: a[i]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment