module types_linq.more.more_enumerable
class MoreEnumerable[TSource_co]
from types_linq.more import MoreEnumerable
MoreEnumerable provides more query methods. Instances of this class can be created by directly
constructing, using as_more()
, or invoking MoreEnumerable methods that return MoreEnumerable
instead of Enumerable.
These APIs may have breaking changes more frequently than those in Enumerable class because updates in .NET are happening and sometimes ones of these APIs could be moved to Enumerable with modification, or changed to accommodate changes to Enumerable.
- Revisions
v0.2.0: New.
Bases
Members
instancemethod aggregate_right[TAccumulate, TResult](__seed, __func, __result_selector)
- Parameters
__seed:
TAccumulate
__func:
Callable[[
TSource_co
,
TAccumulate
],
TAccumulate
]
__result_selector:
Callable[[
TAccumulate
],
TResult
]
- Returns
Applies a right-associative accumulator function over the sequence. The seed is used as the initial accumulator value, and the result_selector is used to select the result value.
- Revisions
v1.2.0: Fixed annotation for __func.
instancemethod aggregate_right[TAccumulate](__seed, __func)
- Parameters
__seed:
TAccumulate
__func:
Callable[[
TSource_co
,
TAccumulate
],
TAccumulate
]
- Returns
Applies a right-associative accumulator function over the sequence. The seed is used as the initial accumulator value.
- Example
>>> values = [9, 4, 2] >>> MoreEnumerable(values).aggregate_right('null', lambda e, rr: f'(cons {e} {rr})') '(cons 9 (cons 4 (cons 2 null)))'
- Revisions
v1.2.0: Fixed annotation for __func.
instancemethod aggregate_right(__func)
- Parameters
__func:
Callable[[
TSource_co
,
TSource_co
],
TSource_co
]
- Returns
Applies a right-associative accumulator function over the sequence. Raises InvalidOperationError
if there is no value in the sequence.
- Example
>>> values = ['9', '4', '2', '5'] >>> MoreEnumerable(values).aggregate_right(lambda e, rr: f'({e}+{rr})') '(9+(4+(2+5)))'
- Revisions
v1.2.0: Fixed annotation for __func.
instancemethod as_more()
- Returns
Returns the original MoreEnumerable reference.
instancemethod consume()
- Returns
None
Consumes the sequence completely. This method iterates the sequence immediately and does not save any intermediate data.
- Revisions
v1.1.0: New.
instancemethod cycle(count=None)
- Parameters
count:
Optional[int]
- Returns
Repeats the sequence count
times.
If count
is None
, the sequence is infinite. Raises InvalidOperationError
if count
is negative.
- Example
>>> MoreEnumerable([1, 2, 3]).cycle(3).to_list() [1, 2, 3, 1, 2, 3, 1, 2, 3]
- Revisions
v1.1.0: New.
instancemethod enumerate(start=0)
- Parameters
start:
int
- Returns
MoreEnumerable
[Tuple[int,
TSource_co
]]
Returns a sequence of tuples containing the index and the value from the source sequence. start
is used to specify the starting index.
- Example
>>> ints = [2, 4, 6] >>> MoreEnumerable(ints).enumerate().to_list() [(0, 2), (1, 4), (2, 6)]
- Revisions
v1.0.0: New.
instancemethod except_by2(second, key_selector)
- Parameters
second:
Iterable[
TSource_co
]
key_selector:
Callable[[
TSource_co
], object]
- Returns
Produces the set difference of two sequences: self - second, according to a key selector that determines “distinctness”. Note the second iterable is homogenous to self.
- Example
>>> first = [(16, 'x'), (9, 'y'), (12, 'd'), (16, 't')] >>> second = [(24, 'd'), (77, 'y')] >>> MoreEnumerable(first).except_by2(second, lambda x: x[1]).to_list() [(16, 'x'), (16, 't')]
- Revisions
v1.0.0: Renamed from
except_by()
to this name to accommodate an update to Enumerable class.v0.2.1: Added preliminary support for unhashable keys.
instancemethod flatten()
- Returns
MoreEnumerable
[Any]
Flattens the sequence containing arbitrarily-nested subsequences.
Note: the nested objects must be Iterable to be flatten.
Instances of str
or bytes
are not flattened.
- Example
>>> lst = ['apple', ['orange', ['juice', 'mango'], 'delta function']] >>> MoreEnumerable(lst).flatten().to_list() ['apple', 'orange', 'juice', 'mango', 'delta function']
instancemethod flatten(__predicate)
- Parameters
__predicate:
Callable[[Iterable[Any]], bool]
- Returns
MoreEnumerable
[Any]
Flattens the sequence containing arbitrarily-nested subsequences. A predicate function determines whether a nested iterable should be flattened or not.
Note: the nested objects must be Iterable to be flatten.
instancemethod flatten2(selector)
- Parameters
selector:
Callable[[Any], Optional[Iterable[object]]]
- Returns
MoreEnumerable
[Any]
Flattens the sequence containing arbitrarily-nested subsequences. A selector is used to select a subsequence based on the object’s properties. If the selector returns None, then the object is considered a leaf.
instancemethod for_each(action)
- Parameters
action:
Callable[[
TSource_co
], object]
- Returns
None
Executes the given function on each element in the source sequence. The return values are discarded.
- Example
>>> def gen(): ... yield 116; yield 35; yield -9 >>> Enumerable(gen()).where(lambda x: x > 0).as_more().for_each(print) 116 35
instancemethod for_each2(action)
- Parameters
action:
Callable[[
TSource_co
, int], object]
- Returns
None
Executes the given function on each element in the source sequence. Each element’s index is used in the logic of the function. The return values are discarded.
instancemethod interleave(*iters)
- Parameters
*iters:
Iterable[
TSource_co
]
- Returns
Interleaves the elements of two or more sequences into a single sequence, skipping sequences if they are consumed.
- Example
>>> MoreEnumerable(['1', '2']).interleave(['4', '5', '6'], ['7', '8', '9']).to_list() ['1', '4', '7', '2', '5', '8', '6', '9']
instancemethod maxima_by[TSupportsLessThan](selector)
- Parameters
selector:
Callable[[
TSource_co
],
TSupportsLessThan
]
- Returns
Returns the maximal elements of the sequence based on the given selector.
- Example
>>> strings = ['foo', 'bar', 'cheese', 'orange', 'baz', 'spam', 'egg', 'toasts', 'dish'] >>> MoreEnumerable(strings).maxima_by(len).to_list() ['cheese', 'orange', 'toasts'] >>> MoreEnumerable(strings).maxima_by(lambda x: x.count('e')).first() 'cheese'
instancemethod maxima_by[TKey](selector, __comparer)
- Parameters
selector:
Callable[[
TSource_co
],
TKey
]
- Returns
Returns the maximal elements of the sequence based on the given selector and the comparer.
Such comparer takes two values and return positive ints when lhs > rhs, negative ints if lhs < rhs, and 0 if they are equal.
instancemethod minima_by[TSupportsLessThan](selector)
- Parameters
selector:
Callable[[
TSource_co
],
TSupportsLessThan
]
- Returns
Returns the minimal elements of the sequence based on the given selector.
instancemethod minima_by[TKey](selector, __comparer)
- Parameters
selector:
Callable[[
TSource_co
],
TKey
]
- Returns
Returns the minimal elements of the sequence based on the given selector and the comparer.
Such comparer takes two values and return positive ints when lhs > rhs, negative ints if lhs < rhs, and 0 if they are equal.
instancemethod pipe(action)
- Parameters
action:
Callable[[
TSource_co
], object]
- Returns
Executes the given action on each element in the sequence and yields it. Return values of action are discarded.
- Example
>>> store = set() >>> MoreEnumerable([1, 2, 2, 1]).pipe(store.add).where(lambda x: x % 2 == 0).to_list() [2, 2] >>> store {1, 2}
- Revisions
v0.2.1: New.
instancemethod pre_scan[TAccumulate](identity, transformation)
- Parameters
identity:
TAccumulate
transformation:
Callable[[
TAccumulate
,
TSource_co
],
TAccumulate
]
- Returns
Performs a pre-scan (exclusive prefix sum) over the sequence. Such scan returns an equal-length sequence where the first element is the identity, and i-th element (i>1) is the sum of the first i-1 (and identity) elements in the original sequence.
- Example
>>> values = [9, 4, 2, 5, 7] >>> MoreEnumerable(values).pre_scan(0, lambda acc, e: acc + e).to_list() [0, 9, 13, 15, 20] >>> MoreEnumerable([]).pre_scan(0, lambda acc, e: acc + e).to_list() []
- Revisions
v1.2.0: New.
instancemethod rank[TSupportsLessThan](*, method=RankMethods.dense)
- Constraint
self:
MoreEnumerable
[
TSupportsLessThan
]
- Parameters
method:
RankMethods
- Returns
MoreEnumerable
[int]
Ranks each item in the sequence in descending order using the method provided.
- Example
>>> scores = [1, 4, 77, 23, 23, 4, 9, 0, -7, 101, 23] >>> MoreEnumerable(scores).rank().to_list() [6, 5, 2, 3, 3, 5, 4, 7, 8, 1, 3] # 101 is largest, so has rank of 1 >>> MoreEnumerable(scores).rank(method=RankMethods.competitive).to_list() [9, 7, 2, 3, 3, 7, 6, 10, 11, 1, 3] # there are no 4th or 5th since there # are three 3rd's >>> MoreEnumerable(scores).rank(method=RankMethods.ordinal).to_list() [9, 7, 2, 3, 4, 8, 6, 10, 11, 1, 5] # as in sorting
- Revisions
v1.2.1: Added method parameter to support more ranking methods.
v1.0.0: New.
instancemethod rank(__comparer, *, method=RankMethods.dense)
- Parameters
__comparer:
Callable[[
TSource_co
,
TSource_co
], int]
method:
RankMethods
- Returns
MoreEnumerable
[int]
Ranks each item in the sequence in descending order using the given comparer and the method.
Such comparer takes two values and return positive ints when lhs > rhs, negative ints if lhs < rhs, and 0 if they are equal.
- Revisions
v1.2.1: Added method parameter to support more ranking methods.
v1.0.0: New.
instancemethod rank_by[TSupportsLessThan](key_selector, *, method=RankMethods.dense)
- Parameters
key_selector:
Callable[[
TSource_co
],
TSupportsLessThan
]
method:
RankMethods
- Returns
MoreEnumerable
[int]
Ranks each item in the sequence in descending order using the given selector and the method.
- Example
>>> scores = [ ... {'name': 'Frank', 'score': 75}, ... {'name': 'Alica', 'score': 90}, ... {'name': 'Erika', 'score': 99}, ... {'name': 'Rogers', 'score': 90}, ... ] >>> MoreEnumerable(scores).rank_by(lambda x: x['score']) \ ... .zip(scores) \ ... .group_by(lambda t: t[0], lambda t: t[1]['name']) \ ... .to_dict(lambda g: g.key, lambda g: g.to_list()) {3: ['Frank'], 2: ['Alica', 'Rogers'], 1: ['Erika']}
- Revisions
v1.2.1: Added method parameter to support more ranking methods.
v1.0.0: New.
instancemethod rank_by[TKey](key_selector, __comparer, *, method=RankMethods.dense)
- Parameters
key_selector:
Callable[[
TSource_co
],
TKey
]
method:
RankMethods
- Returns
MoreEnumerable
[int]
Ranks each item in the sequence in descending order using the given selector, comparer and the method.
Such comparer takes two values and return positive ints when lhs > rhs, negative ints if lhs < rhs, and 0 if they are equal.
- Revisions
v1.2.1: Added method parameter to support more ranking methods.
v1.0.0: New.
instancemethod run_length_encode()
- Returns
MoreEnumerable
[Tuple[
TSource_co
, int]]
Run-length encodes the sequence into a sequence of tuples where each tuple contains an
(the first) element and its number of contingent occurrences, where equality is based on
==
.
- Example
>>> MoreEnumerable('abbcaeeeaa').run_length_encode().to_list() [('a', 1), ('b', 2), ('c', 1), ('a', 1), ('e', 3), ('a', 2)]
- Revisions
v1.1.0: New.
instancemethod run_length_encode(__comparer)
- Parameters
__comparer:
Callable[[
TSource_co
,
TSource_co
], bool]
- Returns
MoreEnumerable
[Tuple[
TSource_co
, int]]
Run-length encodes the sequence into a sequence of tuples where each tuple contains an (the first) element and its number of contingent occurrences, where equality is determined by the comparer.
- Example
>>> MoreEnumerable('abBBbcaEeeff') \ >>> .run_length_encode(lambda x, y: x.lower() == y.lower()).to_list() [('a', 1), ('b', 4), ('c', 1), ('a', 1), ('E', 3), ('f', 2)]
- Revisions
v1.1.0: New.
instancemethod scan(__transformation)
- Parameters
__transformation:
Callable[[
TSource_co
,
TSource_co
],
TSource_co
]
- Returns
Performs a inclusive prefix sum over the sequence. Such scan returns an equal-length sequence where the i-th element is the sum of the first i elements in the original sequence.
- Example
>>> values = [9, 4, 2, 5, 7] >>> MoreEnumerable(values).scan(lambda acc, e: acc + e).to_list() [9, 13, 15, 20, 27] >>> MoreEnumerable([]).scan(lambda acc, e: acc + e).to_list() []
- Example
>>> # running max >>> fruits = ['apple', 'mango', 'orange', 'passionfruit', 'grape'] >>> MoreEnumerable(fruits).scan(lambda acc, e: e if len(e) > len(acc) else acc).to_list() ['apple', 'apple', 'orange', 'passionfruit', 'passionfruit']
- Revisions
v1.2.0: New.
instancemethod scan[TAccumulate](__seed, __transformation)
- Parameters
__seed:
TAccumulate
__transformation:
Callable[[
TAccumulate
,
TSource_co
],
TAccumulate
]
- Returns
Like Enumerable.aggregate(seed, transformation) except that the intermediate results are included in the result sequence.
- Example
>>> Enumerable.range(1, 5).as_more().scan(-1, lambda acc, e: acc * e).to_list() [-1, -1, -2, -6, -24, -120]
- Revisions
v1.2.0: New.
instancemethod scan_right(__func)
- Parameters
__func:
Callable[[
TSource_co
,
TSource_co
],
TSource_co
]
- Returns
Performs a right-associative inclusive prefix sum over the sequence. This is the right-associative version of MoreEnumerable.scan(func).
- Example
>>> values = ['9', '4', '2', '5'] >>> MoreEnumerable(values).scan_right(lambda e, rr: f'({e}+{rr})').to_list() ['(9+(4+(2+5)))', '(4+(2+5))', '(2+5)', '5'] >>> MoreEnumerable([]).scan_right(lambda e, rr: e + rr).to_list() []
- Revisions
v1.2.0: New.
instancemethod scan_right[TAccumulate](__seed, __func)
- Parameters
__seed:
TAccumulate
__func:
Callable[[
TSource_co
,
TAccumulate
],
TAccumulate
]
- Returns
The right-associative version of MoreEnumerable.scan(seed, func).
- Example
>>> values = [9, 4, 2] >>> MoreEnumerable(values).scan_right('null', lambda e, rr: f'(cons {e} {rr})').to_list() ['(cons 9 (cons 4 (cons 2 null)))', '(cons 4 (cons 2 null))', '(cons 2 null)', 'null']
- Revisions
v1.2.0: New.
instancemethod segment(new_segment_predicate)
- Parameters
new_segment_predicate:
Callable[[
TSource_co
], bool]
- Returns
Splits the sequence into segments by using a detector function that returns True to signal a new segment.
- Example
>>> values = [0, 1, 2, 4, -4, -2, 6, 2, -2] >>> MoreEnumerable(values).segment(lambda x: x < 0).select(lambda x: x.to_list()).to_list() [[0, 1, 2, 4], [-4], [-2, 6, 2], [-2]]
- Revisions
v1.2.0: New.
instancemethod segment2(new_segment_predicate)
- Parameters
new_segment_predicate:
Callable[[
TSource_co
, int], bool]
- Returns
Splits the sequence into segments by using a detector function that returns True to signal a new segment. The element’s index is used in the detector function.
- Example
>>> values = [0, 1, 2, 4, -4, -2, 6, 2, -2] >>> MoreEnumerable(values).segment2(lambda x, i: x < 0 or i % 3 == 0) \ ... .select(lambda x: x.to_list()) \ ... .to_list() [[0, 1, 2], [4], [-4], [-2], [6, 2], [-2]]
- Revisions
v1.2.0: New.
instancemethod segment3(new_segment_predicate)
- Parameters
new_segment_predicate:
Callable[[
TSource_co
,
TSource_co
, int], bool]
- Returns
Splits the sequence into segments by using a detector function that returns True to signal a new segment. The last element and the current element’s index are used in the detector function.
- Example
>>> values = [0, 1, 2, 4, -4, -2, 6, 2, -2] >>> MoreEnumerable(values).segment3(lambda curr, prev, i: curr * prev < 0) \ ... .select(lambda x: x.to_list()) \ ... .to_list() [[0, 1, 2, 4], [-4, -2], [6, 2], [-2]]
- Revisions
v1.2.0: New.
staticmethod traverse_breath_first[TSource](root, children_selector)
- Parameters
root:
TSource
- Returns
Traverses the tree (graph) from the root node in a breath-first fashion. A selector is used to select children of each node.
Graphs are not checked for cycles or duplicates visits. If the resulting sequence needs to be finite then it is the responsibility of children_selector to ensure that duplicate nodes are not visited.
- Example
>>> tree = { 3: [1, 4], 1: [0, 2], 4: [5] } >>> MoreEnumerable.traverse_breath_first(3, lambda x: tree.get(x, [])) \ >>> .to_list() [3, 1, 4, 0, 2, 5]
staticmethod traverse_depth_first[TSource](root, children_selector)
- Parameters
root:
TSource
- Returns
Traverses the tree (graph) from the root node in a depth-first fashion. A selector is used to select children of each node.
Graphs are not checked for cycles or duplicates visits. If the resulting sequence needs to be finite then it is the responsibility of children_selector to ensure that duplicate nodes are not visited.
- Example
>>> tree = { 3: [1, 4], 1: [0, 2], 4: [5] } >>> MoreEnumerable.traverse_depth_first(3, lambda x: tree.get(x, [])) \ >>> .to_list() [3, 1, 0, 2, 4, 5]
instancemethod traverse_topological(children_selector)
- Parameters
children_selector:
Callable[[
TSource_co
], Iterable[
TSource_co
]]
- Returns
Traverses the graph in topological order, A selector is used to select children of each node. The ordering created from this method is a variant of depth-first traversal and ensures duplicate nodes are output once.
To invoke this method, the self sequence contains nodes with zero in-degrees to start the iteration. Passing a list of all nodes is allowed although not required.
Raises DirectedGraphNotAcyclicError
if the directed graph contains a cycle and the
topological ordering cannot be produced.
- Example
>>> adj = { 5: [2, 0], 4: [0, 1], 2: [3], 3: [1] } >>> MoreEnumerable([5, 4]).traverse_topological(lambda x: adj.get(x, [])) \ >>> .to_list() [5, 2, 3, 4, 0, 1]
- Revisions
v1.2.1: New.
instancemethod traverse_topological2(children_selector, key_selector)
- Parameters
children_selector:
Callable[[
TSource_co
], Iterable[
TSource_co
]]
key_selector:
Callable[[
TSource_co
], object]
- Returns
Traverses the graph in topological order, A selector is used to select children of each node. The ordering created from this method is a variant of depth-first traversal and ensures duplicate nodes are output once. A key selector is used to determine equality between nodes.
To invoke this method, the self sequence contains nodes with zero in-degrees to start the iteration. Passing a list of all nodes is allowed although not required.
Raises DirectedGraphNotAcyclicError
if the directed graph contains a cycle and the
topological ordering cannot be produced.
- Revisions
v1.2.1: New.