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
Example #2
0
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
Example #7
0
    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))
Example #8
0
 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)
     )