Source code for owlmixin.owlcollections

# coding: utf-8

import functools
from collections import deque
from itertools import chain, filterfalse, groupby, islice, takewhile, tee
from typing import (
    Any,
    Callable,
    Dict,
    Generic,
    Iterable,
    Iterator,
    List,
    Tuple,
    TypeVar,
    Union,
)

from owlmixin.owloption import TOption
from owlmixin.transformers import (
    CsvTransformer,
    DictsTransformer,
    DictTransformer,
    JsonTransformer,
    TableTransformer,
    YamlTransformer,
)

T = TypeVar("T")
U = TypeVar("U")
K = TypeVar("K")


[docs]class TList( list, DictsTransformer, JsonTransformer, YamlTransformer, CsvTransformer, TableTransformer, Generic[T], ): def __add__(self, values: list) -> "TList[T]": return TList(list(self) + values)
[docs] def to_iterator(self) -> "TIterator[T]": """ Usage: >>> it = TList([1, 2, 3]).to_iterator() >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ return TIterator(self)
[docs] def get(self, index: int) -> TOption[T]: # TODO: Rename -> not implemented super class """ Usage: >>> TList([1, 2, 3, 4, 5]).get(3) Option --> 4 >>> TList([1, 2, 3, 4, 5]).get(5) Option --> None """ return TOption(self[index]) if len(self) > index else TOption(None)
[docs] def for_each(self, func: Callable[[T], None]) -> None: """ Usage: >>> TList([1, 2, 3]).for_each(lambda x: print(str(x))) 1 2 3 """ for x in self: func(x)
[docs] def map(self, func: Callable[[T], U]) -> "TList[U]": """ Usage: >>> TList([1, 2, 3, 4, 5]).map(lambda x: x+1) [2, 3, 4, 5, 6] """ return TList(map(func, self))
[docs] def emap(self, func: Callable[[T, int], U]) -> "TList[U]": """ Usage: >>> TList([10, 20, 30, 40, 50]).emap(lambda x, i: (x+1, i)) [(11, 0), (21, 1), (31, 2), (41, 3), (51, 4)] """ return TList([func(x, i) for i, x in enumerate(self)])
[docs] def flatten(self) -> "TList[U]": """ Usage: >>> TList([[1, 2], [3, 4]]).flatten() [1, 2, 3, 4] """ return TList(chain.from_iterable(self))
[docs] def flat_map(self, func: Callable[[T], List[U]]) -> "TList[U]": """ Usage: >>> TList([1, 2, 3]).flat_map(lambda x: [x, x+1]) [1, 2, 2, 3, 3, 4] """ return self.map(func).flatten()
[docs] def filter(self, func: Callable[[T], bool]) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).filter(lambda x: x > 3) [4, 5] """ return TList([x for x in self if func(x)])
[docs] def reject(self, func: Callable[[T], bool]) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).reject(lambda x: x > 3) [1, 2, 3] """ return TList([x for x in self if not func(x)])
[docs] def head(self) -> TOption[T]: """ Usage: >>> TList([1, 2, 3, 4, 5]).head() Option --> 1 >>> TList([]).head() Option --> None """ return self.get(0)
[docs] def take(self, size_: int) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).take(3) [1, 2, 3] """ return TList(self[:size_])
[docs] def take_while(self, func: Callable[[T], bool]) -> "TList[T]": """ Usage: >>> TList([1, 2, 30, 4, 50]).take_while(lambda x: x < 10) [1, 2] """ r = TList[T]() for x in self: if not func(x): return r r.append(x) return r
[docs] def tail(self, size_: int) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).tail(3) [3, 4, 5] """ return TList(self[self.size() - size_ :])
[docs] def uniq(self) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 2, 1]).uniq() [1, 2, 3] """ rs = TList[T]() for e in self: if e not in rs: rs.append(e) return rs
[docs] def uniq_by(self, func: Callable[[T], Any]) -> "TList[T]": """ Usage: >>> TList([1, 2, 3, -2, -1]).uniq_by(lambda x: x**2) [1, 2, 3] """ rs = TList[T]() for e in self: if func(e) not in rs.map(func): rs.append(e) return rs
[docs] def partition(self, func: Callable[[T], bool]) -> Tuple["TList[T]", "TList[T]"]: """ Usage: >>> TList([1, 2, 3, 4, 5]).partition(lambda x: x > 3) ([1, 2, 3], [4, 5]) """ return self.reject(func), self.filter(func)
[docs] def group_by(self, to_key: Callable[[T], str]) -> "TDict[TList[T]]": """ Usage: >>> TList([1, 2, 3, 4, 5]).group_by(lambda x: x % 2).to_json() '{"0": [2,4],"1": [1,3,5]}' """ ret = TDict[TList[T]]() for v in self: k = to_key(v) ret.setdefault(k, TList()) ret[k].append(v) return ret
[docs] def key_by(self, to_key: Callable[[T], str]) -> "TDict[T]": """ :param to_key: value -> key Usage: >>> TList(['a1', 'b2', 'c3']).key_by(lambda x: x[0]).to_json() '{"a": "a1","b": "b2","c": "c3"}' >>> TList([1, 2, 3, 4, 5]).key_by(lambda x: x % 2).to_json() '{"0": 4,"1": 5}' """ return TDict({to_key(x): x for x in self})
[docs] def order_by(self, func: Callable[[T], Any], reverse: bool = False) -> "TList[T]": """ Usage: >>> TList([12, 25, 31, 40, 57]).order_by(lambda x: x % 10) [40, 31, 12, 25, 57] >>> TList([12, 25, 31, 40, 57]).order_by(lambda x: x % 10, reverse=True) [57, 25, 12, 31, 40] """ return TList(sorted(self, key=func, reverse=reverse))
[docs] def concat(self, values: List[T], first: bool = False) -> "TList[T]": """ Usage: >>> TList([1, 2]).concat(TList([3, 4])) [1, 2, 3, 4] >>> TList([1, 2]).concat(TList([3, 4]), first=True) [3, 4, 1, 2] """ return TList(values) + self if first else self + values # type: ignore
[docs] def reduce(self, func: Callable[[U, T], U], init_value: U) -> U: """ Usage: >>> TList([1, 2, 3, 4, 5]).reduce(lambda t, x: t + 2*x, 100) 130 """ return functools.reduce(func, self, init_value)
[docs] def sum(self) -> Union[int, float]: """ Usage: >>> TList([1, 2, 3, 4, 5]).sum() 15 """ return sum(self)
[docs] def sum_by(self, func: Callable[[T], Union[int, float]]) -> Union[int, float]: """ Usage: >>> TList([1, 2, 3, 4, 5]).sum_by(lambda x: x*2) 30 """ return self.map(func).sum()
[docs] def count_by(self, func: Callable[[T], Any]) -> "TDict[int]": """ Usage: >>> TList([1, 11, 25, 35, 21, 4]).count_by(lambda x: x % 10) {1: 3, 5: 2, 4: 1} """ ret = TDict[int]() for v in self: k = func(v) ret.setdefault(k, 0) ret[k] += 1 return ret
[docs] def size(self) -> int: """ Usage: >>> TList([1, 2, 3, 4, 5]).size() 5 """ return len(self)
[docs] def join(self, joint: str) -> str: """ Usage: >>> TList(['A', 'B', 'C']).join("-") 'A-B-C' """ return joint.join(self)
[docs] def unlines(self, *, crlf: bool = False) -> str: r""" Usage: >>> TList(['aaa', 'bbb', 'ccc']).unlines() 'aaa\nbbb\nccc' >>> TList(['A', 'B', 'C']).unlines(crlf=True) 'A\r\nB\r\nC' """ return self.join("\r\n" if crlf else "\n")
[docs] def find(self, func: Callable[[T], bool]) -> TOption[T]: """ Usage: >>> TList([1, 2, 3, 4, 5]).find(lambda x: x > 3) Option --> 4 >>> TList([1, 2, 3, 4, 5]).find(lambda x: x > 6) Option --> None """ for x in self: if func(x): return TOption(x) return TOption(None)
[docs] def all(self, func: Callable[[T], bool]) -> bool: """ Usage: >>> TList([1, 2, 3, 4, 5]).all(lambda x: x > 0) True >>> TList([1, 2, 3, 4, 5]).all(lambda x: x > 1) False """ return all([func(x) for x in self])
[docs] def any(self, func: Callable[[T], bool]) -> bool: """ Usage: >>> TList([1, 2, 3, 4, 5]).any(lambda x: x > 4) True >>> TList([1, 2, 3, 4, 5]).any(lambda x: x > 5) False """ return any([func(x) for x in self])
[docs] def intersection(self, values: "List[T]") -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).intersection([2, 4, 6]) [2, 4] """ return self.filter(lambda x: x in values)
[docs] def not_intersection(self, values: "List[T]") -> "TList[T]": """ Usage: >>> TList([1, 2, 3, 4, 5]).not_intersection([2, 4, 6]) [1, 3, 5] """ return self.reject(lambda x: x in values)
def reverse(self) -> "TList[T]": # type: ignore # TODO: Rename -> not implemented super class """ Usage: >>> TList([1, 2, 3]).reverse() [3, 2, 1] """ return TList(reversed(self))
[docs]class TIterator( DictsTransformer, JsonTransformer, YamlTransformer, CsvTransformer, TableTransformer, Generic[T], ): __inner_iterator: Iterator def __init__(self, iterable: Iterable): """ Usage: >>> it = TIterator([1, 2, 3]) >>> list(it) [1, 2, 3] >>> list(it) [] """ self.__inner_iterator = iterable.__iter__() def __iter__(self) -> Iterator: return self.__inner_iterator def __next__(self) -> T: return self.__inner_iterator.__next__()
[docs] def to_list(self) -> "TList[T]": """ Usage: >>> TIterator([1, 2, 3]).to_list() [1, 2, 3] """ return TList(self)
[docs] def next_at(self, index: int) -> TOption[T]: """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]) >>> it.next_at(1) Option --> 2 >>> it.next_at(1) Option --> 4 >>> it.next_at(1) Option --> None """ return TOption(next(islice(self, index, None), None))
[docs] def for_each(self, func: Callable[[T], None]) -> None: """ Usage: >>> TIterator([1, 2, 3]).for_each(lambda x: print(str(x))) 1 2 3 """ for x in self: func(x)
[docs] def map(self, func: Callable[[T], U]) -> "TIterator[U]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).map(lambda x: x+1) >>> it.to_list() [2, 3, 4, 5, 6] >>> it.to_list() [] """ return TIterator(map(func, self))
[docs] def emap(self, func: Callable[[T, int], U]) -> "TIterator[U]": """ Usage: >>> it = TIterator([10, 20, 30, 40, 50]).emap(lambda x, i: (x+1, i)) >>> it.to_list() [(11, 0), (21, 1), (31, 2), (41, 3), (51, 4)] >>> it.to_list() [] """ return TIterator(func(x, i) for (i, x) in enumerate(self))
[docs] def filter(self, func: Callable[[T], bool]) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).filter(lambda x: x > 3) >>> it.to_list() [4, 5] >>> it.to_list() [] """ return TIterator(filter(func, self))
[docs] def reject(self, func: Callable[[T], bool]) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).reject(lambda x: x > 3) >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ return TIterator(filterfalse(func, self))
[docs] def flatten(self) -> "TIterator[U]": """ Usage: >>> it = TIterator([[1, 2], [3, 4]]).flatten() >>> it.to_list() [1, 2, 3, 4] >>> it.to_list() [] """ return TIterator(chain.from_iterable(self))
[docs] def flat_map(self, func: Callable[[T], List[U]]) -> "TIterator[U]": """ Usage: >>> it = TIterator([1, 2, 3]).flat_map(lambda x: [x, x+1]) >>> it.to_list() [1, 2, 2, 3, 3, 4] >>> it.to_list() [] """ return self.map(func).flatten()
[docs] def head(self) -> TOption[T]: """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]) >>> it.head().get() 1 >>> it.head().get() 2 """ return TOption(next(self.__iter__(), None))
[docs] def take(self, size_: int) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).take(3) >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ return TIterator(islice(self, size_))
[docs] def take_while(self, func: Callable[[T], bool]) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 30, 4, 50]).take_while(lambda x: x < 10) >>> it.to_list() [1, 2] >>> it.to_list() [] """ return TIterator(takewhile(func, self))
[docs] def tail(self, size_: int) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).tail(3) >>> it.to_list() [3, 4, 5] >>> it.to_list() [] """ return TIterator(deque(self, maxlen=size_))
[docs] def uniq(self) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 2, 1]).uniq() >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ return self.uniq_by()
[docs] def uniq_by(self, func: Callable[[T], Any] = None) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, -2, -1]).uniq_by(lambda x: x**2) >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ def make_generator(): seen = set() seen_add = seen.add if func is None: for element in filterfalse(seen.__contains__, self): seen_add(element) yield element else: for element in self: k = func(element) if k not in seen: seen_add(k) yield element return TIterator(make_generator())
[docs] def partition( self, func: Callable[[T], bool] ) -> Tuple["TIterator[T]", "TIterator[T]"]: """ Usage: >>> ng, ok = TIterator([1, 2, 3, 4, 5]).partition(lambda x: x > 3) >>> ng.to_list() [1, 2, 3] >>> ng.to_list() [] >>> ok.to_list() [4, 5] >>> ok.to_list() [] """ t1, t2 = tee(self) return TIterator(filterfalse(func, t1)), TIterator(filter(func, t2))
[docs] def group_by(self, to_key: Callable[[T], str]) -> "TDict[TList[T]]": """ Usage: >>> TIterator([1, 2, 3, 4, 5]).group_by(lambda x: x % 2).to_json() '{"0": [2,4],"1": [1,3,5]}' """ return TDict( {k: TList(v) for k, v in groupby(sorted(self, key=to_key), to_key)} )
[docs] def key_by(self, to_key: Callable[[T], str]) -> "TDict[T]": """ :param to_key: value -> key Usage: >>> TIterator(['a1', 'b2', 'c3']).key_by(lambda x: x[0]).to_json() '{"a": "a1","b": "b2","c": "c3"}' >>> TIterator([1, 2, 3, 4, 5]).key_by(lambda x: x % 2).to_json() '{"0": 4,"1": 5}' """ return TDict({to_key(x): x for x in self})
[docs] def order_by( self, func: Callable[[T], Any], reverse: bool = False ) -> "TIterator[T]": """ Usage: >>> it = TIterator([12, 25, 31, 40, 57]).order_by(lambda x: x % 10) >>> it.to_list() [40, 31, 12, 25, 57] >>> it.to_list() [] >>> it = TIterator([12, 25, 31, 40, 57]).order_by(lambda x: x % 10, reverse=True) >>> it.to_list() [57, 25, 12, 31, 40] >>> it.to_list() [] """ return TIterator(sorted(self, key=func, reverse=reverse))
[docs] def concat(self, values: "Iterable[T]", first: bool = False) -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2]).concat(TIterator([3, 4])) >>> it.to_list() [1, 2, 3, 4] >>> it.to_list() [] >>> it = TIterator([1, 2]).concat([3, 4], first=True) >>> it.to_list() [3, 4, 1, 2] >>> it.to_list() [] """ return TIterator(chain(values, self) if first else chain(self, values))
[docs] def reduce(self, func: Callable[[U, T], U], init_value: U) -> U: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).reduce(lambda t, x: t + 2*x, 100) 130 """ return functools.reduce(func, self, init_value)
[docs] def sum(self) -> Union[int, float]: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).sum() 15 """ return sum(self)
[docs] def sum_by(self, func: Callable[[T], Union[int, float]]) -> Union[int, float]: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).sum_by(lambda x: x*2) 30 """ return self.map(func).sum()
[docs] def count_by(self, func: Callable[[T], Any]) -> "TDict[int]": """ Usage: >>> it = TIterator([1, 11, 25, 35, 21, 4]) >>> it.count_by(lambda x: x % 10) {1: 3, 5: 2, 4: 1} >>> it.to_list() [] """ ret = TDict[int]() for v in self: k = func(v) ret.setdefault(k, 0) ret[k] += 1 return ret
[docs] def join(self, joint: str) -> str: """ Usage: >>> TIterator(['A', 'B', 'C']).join("-") 'A-B-C' """ return joint.join(self)
[docs] def unlines(self, *, crlf: bool = False) -> str: r""" Usage: >>> TIterator(['aaa', 'bbb', 'ccc']).unlines() 'aaa\nbbb\nccc' >>> TIterator(['A', 'B', 'C']).unlines(crlf=True) 'A\r\nB\r\nC' """ return self.join("\r\n" if crlf else "\n")
[docs] def find(self, func: Callable[[T], bool]) -> TOption[T]: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).find(lambda x: x > 3) Option --> 4 >>> TIterator([1, 2, 3, 4, 5]).find(lambda x: x > 6) Option --> None """ for x in self: if func(x): return TOption(x) return TOption(None)
[docs] def all(self, func: Callable[[T], bool]) -> bool: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).all(lambda x: x > 0) True >>> TIterator([1, 2, 3, 4, 5]).all(lambda x: x > 1) False """ return all(self.map(func))
[docs] def any(self, func: Callable[[T], bool]) -> bool: """ Usage: >>> TIterator([1, 2, 3, 4, 5]).any(lambda x: x > 4) True >>> TIterator([1, 2, 3, 4, 5]).any(lambda x: x > 5) False """ return any(self.map(func))
[docs] def intersection(self, values: "Iterable[T]") -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).intersection([2, 4, 6]) >>> it.to_list() [2, 4] >>> it.to_list() [] """ return self.filter(lambda x: x in values)
[docs] def not_intersection(self, values: "Iterable[T]") -> "TIterator[T]": """ Usage: >>> it = TIterator([1, 2, 3, 4, 5]).not_intersection([2, 4, 6]) >>> it.to_list() [1, 3, 5] >>> it.to_list() [] """ return self.reject(lambda x: x in values)
def reverse(self) -> "TIterator[T]": # type: ignore # TODO: Rename -> not implemented super class """ Usage: >>> it = TIterator([1, 2, 3]).reverse() >>> it.to_list() [3, 2, 1] >>> it.to_list() [] """ return TIterator(reversed(list(self)))
[docs]class TDict(dict, DictTransformer, JsonTransformer, YamlTransformer, Generic[T]): @property def _dict(self) -> dict: return dict(self) def get(self, key: K) -> TOption[T]: # type: ignore """ Usage: >>> TDict(k1=1, k2=2, k3=3).get("k2") Option --> 2 >>> TDict(k1=1, k2=2, k3=3).get("unknown") Option --> None """ return TOption(self[key]) if key in self else TOption(None)
[docs] def map(self, func: Callable[[K, T], U]) -> TIterator[U]: """ Usage: >>> it = TDict(k1=1, k2=2, k3=3).map(lambda k, v: v*2) >>> sorted(it.to_list()) [2, 4, 6] >>> it.to_list() [] """ return TIterator(func(k, self[k]) for k in self)
[docs] def map_values(self, func: Callable[[T], U]) -> "TDict[U]": """ Usage: >>> TDict(k1=1, k2=2, k3=3).map_values(lambda x: x*2) == { ... "k1": 2, ... "k2": 4, ... "k3": 6 ... } True """ return TDict({k: func(v) for k, v in self.items()})
[docs] def map_values2(self, func: Callable[[K, T], U]) -> "TDict[U]": """ Usage: >>> TDict(k1=1, k2=2, k3=3).map_values2(lambda k, v: f'{k} -> {v*2}') == { ... "k1": "k1 -> 2", ... "k2": "k2 -> 4", ... "k3": "k3 -> 6" ... } True """ return TDict({k: func(k, v) for k, v in self.items()})
[docs] def filter(self, func: Callable[[K, T], bool]) -> TIterator[T]: """ Usage: >>> it = TDict(k1=1, k2=2, k3=3).filter(lambda k, v: v < 2) >>> it.to_list() [1] >>> it.to_list() [] """ return TIterator(v for k, v in self.items() if func(k, v))
[docs] def reject(self, func: Callable[[K, T], bool]) -> TIterator[T]: """ Usage: >>> it = TDict(k1=1, k2=2, k3=3).reject(lambda k, v: v < 3) >>> it.to_list() [3] >>> it.to_list() [] """ return TIterator(v for k, v in self.items() if not func(k, v))
[docs] def sum(self) -> Union[int, float]: """ Usage: >>> TDict(k1=1, k2=2, k3=3).sum() 6 """ return sum(self.values())
[docs] def sum_by(self, func: Callable[[K, T], Union[int, float]]) -> Union[int, float]: """ Usage: >>> TDict(k1=1, k2=2, k3=3).sum_by(lambda k, v: v*2) 12 """ return self.map(func).sum()
[docs] def size(self) -> int: """ Usage: >>> TDict(k1=1, k2=2, k3=3).size() 3 """ return len(self)
[docs] def find(self, func: Callable[[K, T], bool]) -> TOption[T]: """ Usage: >>> TDict(k1=1, k2=2, k3=3).find(lambda k, v: v == 2) Option --> 2 >>> TDict(k1=1, k2=2, k3=3).find(lambda k, v: v == 4) Option --> None """ for k, v in self.items(): if func(k, v): return TOption(v) return TOption(None)
[docs] def to_list(self) -> TList[T]: """ Usage: >>> TDict(k1=1, k2=2, k3=3).to_list().order_by(lambda x: x) [1, 2, 3] """ return TList(self[k] for k in self)
[docs] def to_iterator(self) -> TIterator[T]: """ Usage: >>> it = TDict(k1=1, k2=2, k3=3).to_iterator().order_by(lambda x: x) >>> it.to_list() [1, 2, 3] >>> it.to_list() [] """ return TIterator(self[k] for k in self)
[docs] def all(self, func: Callable[[K, T], bool]) -> bool: """ Usage: >>> TDict(k1=1, k2=2, k3=3).all(lambda k, v: v > 0) True >>> TDict(k1=1, k2=2, k3=3).all(lambda k, v: v > 1) False """ return all([func(k, v) for k, v in self.items()])
[docs] def any(self, func: Callable[[K, T], bool]) -> bool: """ Usage: >>> TDict(k1=1, k2=2, k3=3).any(lambda k, v: v > 2) True >>> TDict(k1=1, k2=2, k3=3).any(lambda k, v: v > 3) False """ return any([func(k, v) for k, v in self.items()])
[docs] def assign(self, dict_: Dict[str, T]) -> "TDict[T]": """ Usage: >>> TDict(k1=1, k2=2).assign({'k3': 3}) {'k1': 1, 'k2': 2, 'k3': 3} >>> TDict(k1=1, k2=2).assign(TDict({'k2': 3})) {'k1': 1, 'k2': 3} """ return TDict({**self, **dict_})
[docs] def pick_by(self, func: Callable[[K, T], bool]) -> "TDict[T]": """ Usage: >>> TDict(k1=1, k2=2, k3=3).pick_by(lambda k, v: v > 2) {'k3': 3} """ return TDict({k: v for k, v in self.items() if func(k, v)})
[docs] def omit_by(self, func: Callable[[K, T], bool]) -> "TDict[T]": """ Usage: >>> TDict(k1=1, k2=2, k3=3).omit_by(lambda k, v: v > 2) {'k1': 1, 'k2': 2} """ return TDict({k: v for k, v in self.items() if not func(k, v)})