def iter_with(iterable, context_manager, lazy_tuple=False): ''' Iterate on `iterable`, `with`ing the context manager on every `next`. If `lazy_tuple=True`, returns a `LazyTuple` rather than an iterator. ''' iterator = _iter_with(iterable=iterable, context_manager=context_manager) if lazy_tuple: from python_toolbox import nifty_collections # Avoiding circular import. return nifty_collections.LazyTuple(iterator) else: return iterator
def zip_non_equal(iterables, lazy_tuple=False): ''' Zip the iterables, but only yield the tuples where the items aren't equal. ''' from python_toolbox import logic_tools iterator = (items for items in zip(*iterables) if not logic_tools.all_equal(items)) if lazy_tuple: from python_toolbox import nifty_collections return nifty_collections.LazyTuple(iterator) else: return iterator
def test_double_filter(): (first_iterable, second_iterable) = \ double_filter(lambda value: value % 2 == 0, range(20)) assert tuple(first_iterable) == tuple(range(0, 20, 2)) assert tuple(second_iterable) == tuple(range(1, 20, 2)) (first_iterable, second_iterable) = \ double_filter(lambda value: value % 3 == 0, range(20)) assert tuple(first_iterable) == tuple(range(0, 20, 3)) assert tuple(second_iterable) == tuple(i for i in range(20) if i % 3 != 0) (first_lazy_tuple, second_lazy_tuple) = \ double_filter(lambda value: value % 3 == 0, range(20), lazy_tuple=True) assert isinstance(first_lazy_tuple, nifty_collections.LazyTuple) assert isinstance(second_lazy_tuple, nifty_collections.LazyTuple) assert first_lazy_tuple.collected_data == \ second_lazy_tuple.collected_data == [] assert first_lazy_tuple == nifty_collections.LazyTuple(range(0, 20, 3)) assert second_lazy_tuple == nifty_collections.LazyTuple(i for i in range(20) if i % 3 != 0)
def get_all_contained_counters(counter, use_lazy_tuple=True): ''' Get all counters that are subsets of `counter`. This means all counters that have amounts identical or smaller than `counter` for each of its keys. If `use_lazy_tuple=True` (default), value is returned as a `LazyTuple`, so it may be used both by lazily iterating on it *and* as a tuple. Otherwise an iterator is returned. ''' iterator = _get_all_contained_counters(counter) if use_lazy_tuple: return nifty_collections.LazyTuple(iterator) else: return iterator
def shorten(iterable, length, lazy_tuple=False): ''' Shorten an iterable to `length`. Iterate over the given iterable, but stop after `n` iterations (Or when the iterable stops iteration by itself.) `n` may be infinite. If `lazy_tuple=True`, returns a `LazyTuple` rather than an iterator. ''' iterator = _shorten(iterable=iterable, length=length) if lazy_tuple: from python_toolbox import nifty_collections return nifty_collections.LazyTuple(iterator) else: return iterator
def enumerate(iterable, reverse_index=False, lazy_tuple=False): ''' Iterate over `(i, item)` pairs, where `i` is the index number of `item`. This is an extension of the builtin `enumerate`. What it allows is to get a reverse index, by specifying `reverse_index=True`. This causes `i` to count down to zero instead of up from zero, so the `i` of the last member will be zero. If `lazy_tuple=True`, returns a `LazyTuple` rather than an iterator. ''' iterator = _enumerate(iterable=iterable, reverse_index=reverse_index) if lazy_tuple: from python_toolbox import nifty_collections return nifty_collections.LazyTuple(iterator) else: return iterator
def get_neighbors(self, *, degrees=(1, ), perm_space=None): ''' Get the neighbor permutations of this permutation. This means, get the permutations that are close to this permutation. By default, this means permutations that are one transformation (switching a pair of items) away from this permutation. You can specify a custom sequence of integers to the `degrees` argument to get different degrees of relation. (e.g. specify `degrees=(1, 2)` to get both the closest neighbors and the second-closest neighbors.) ''' from ..map_space import MapSpace if self.is_combination or self.is_recurrent or self.is_partial: raise NotImplementedError if perm_space is None: perm_space = self.nominal_perm_space return MapSpace( perm_space.coerce_perm, nifty_collections.LazyTuple( tuple(perm) for perm in PermSpace(self._perm_sequence, degrees=degrees) if tuple(perm) in perm_space))
def __init__(self, sequences): self.sequences = nifty_collections.LazyTuple( (sequence_tools.ensure_iterable_is_immutable_sequence( sequence, default_type=nifty_collections.LazyTuple) for sequence in sequences) )