def sort_by(collection, callback=None, reverse=False): """Creates a list of elements, sorted in ascending order by the results of running each element in a `collection` through the callback. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. reverse (bool, optional): Whether to reverse the sort. Defaults to ``False``. Returns: list: Sorted list. Example: >>> sort_by({'a': 2, 'b': 3, 'c': 1}) [1, 2, 3] >>> sort_by({'a': 2, 'b': 3, 'c': 1}, reverse=True) [3, 2, 1] >>> sort_by([{'a': 2}, {'a': 3}, {'a': 1}], 'a') [{'a': 1}, {'a': 2}, {'a': 3}] .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return sorted(collection, key=pyd.iteratee(callback), reverse=reverse)
def key_by(collection, iteratee=None): """Creates an object composed of keys generated from the results of running each element of the collection through the given iteratee. Args: collection (list|dict): Collection to iterate over. iteratee (mixed, optional): Iteratee applied per iteration. Returns: dict: Results of indexing by `iteratee`. Example: >>> results = key_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a') >>> assert results == {1: {'a': 1, 'b': 2}, 3: {'a': 3, 'b': 4}} .. versionadded:: 1.0.0 .. versionchanged:: 4.0.0 Renamed from ``index_by`` to ``key_by``. """ ret = {} cbk = pyd.iteratee(iteratee) for value in collection: ret[cbk(value)] = value return ret
def sorted_last_index(array, value, callback=None): """This method is like :func:`sorted_index` except that it returns the highest index at which a value should be inserted into a given sorted array in order to maintain the sort order of the array. Args: array (list): List to inspect. value (mixed): Value to evaluate. callback (mixed, optional): Callback to determine sort key. Returns: int: Highest index. Example: >>> sorted_last_index([1, 2, 2, 3, 4], 2) 3 .. versionadded:: 1.1.0 """ if callback: # Generate array of sorted keys computed using callback. callback = pyd.iteratee(callback) array = sorted(callback(item) for item in array) value = callback(value) return bisect_right(array, value)
def min_by(collection, iteratee=None, default=NoValue): """Retrieves the minimum value of a `collection`. Args: collection (list|dict): Collection to iterate over. iteratee (mixed, optional): Iteratee applied per iteration. default (mixed, optional): Value to return if `collection` is empty. Returns: mixed: Minimum value. Example: >>> min_by([1.8, 1.5, 1.0], math.floor) 1.8 >>> min_by([{'a': 1}, {'a': 2}, {'a': 3}], 'a') {'a': 1} >>> min_by([], default=100) 100 .. versionadded:: 4.0.0 """ if isinstance(collection, dict): collection = collection.values() return min(iterator_with_default(collection, default), key=pyd.iteratee(iteratee))
def index_by(collection, callback=None): """Creates an object composed of keys generated from the results of running each element of the collection through the given callback. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: dict: Results of indexing by `callback`. Example: >>> results = index_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a') >>> assert results == {1: {'a': 1, 'b': 2}, 3: {'a': 3, 'b': 4}} .. versionadded:: 1.0.0 """ ret = {} cbk = pyd.iteratee(callback) for value in collection: ret[cbk(value)] = value return ret
def group_by(collection, callback=None): """Creates an object composed of keys generated from the results of running each element of a `collection` through the callback. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: dict: Results of grouping by `callback`. Example: >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a') >>> assert results == {1: [{'a': 1, 'b': 2}], 3: [{'a': 3, 'b': 4}]} >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], {'a': 1}) >>> assert results == {False: [{'a': 3, 'b': 4}],\ True: [{'a': 1, 'b': 2}]} .. versionadded:: 1.0.0 """ ret = {} cbk = pyd.iteratee(callback) for value in collection: key = cbk(value) ret.setdefault(key, []) ret[key].append(value) return ret
def group_by(collection, iteratee=None): """Creates an object composed of keys generated from the results of running each element of a `collection` through the iteratee. Args: collection (list|dict): Collection to iterate over. iteratee (mixed, optional): Iteratee applied per iteration. Returns: dict: Results of grouping by `iteratee`. Example: >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a') >>> assert results == {1: [{'a': 1, 'b': 2}], 3: [{'a': 3, 'b': 4}]} >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], {'a': 1}) >>> assert results == {False: [{'a': 3, 'b': 4}],\ True: [{'a': 1, 'b': 2}]} .. versionadded:: 1.0.0 """ ret = {} cbk = pyd.iteratee(iteratee) for value in collection: key = cbk(value) ret.setdefault(key, []) ret[key].append(value) return ret
def sorted_index(array, value, callback=None): """Determine the smallest index at which `value` should be inserted into array in order to maintain the sort order of the sorted array. If callback is passed, it will be executed for value and each element in array to compute their sort ranking. The callback is invoked with one argument: ``(value)``. If a property name is passed for callback, the created :func:`pydash.collections.pluck` style callback will return the property value of the given element. If an object is passed for callback, the created :func:`pydash.collections.where` style callback will return ``True`` for elements that have the properties of the given object, else ``False``. Args: array (list): List to inspect. value (mixed): Value to evaluate. callback (mixed, optional): Callback to determine sort key. Returns: int: Smallest index. Example: >>> sorted_index([1, 2, 2, 3, 4], 2) 1 .. versionadded:: 1.0.0 """ if callback: # Generate array of sorted keys computed using callback. callback = pyd.iteratee(callback) array = sorted(callback(item) for item in array) value = callback(value) return bisect_left(array, value)
def min_(collection, callback=None, default=NoValue): """Retrieves the minimum value of a `collection`. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: mixed: Minimum value. Example: >>> min_([1, 2, 3, 4]) 1 >>> min_([{'a': 1}, {'a': 2}, {'a': 3}], 'a') {'a': 1} >>> min_([], default=100) 100 .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return min(_iterator_with_default(collection, default), key=pyd.iteratee(callback))
def max_(collection, callback=None, default=NoValue): """Retrieves the maximum value of a `collection`. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. default: default value when collection is empty Returns: mixed: Maximum value. Example: >>> max_([1, 2, 3, 4]) 4 >>> max_([{'a': 1}, {'a': 2}, {'a': 3}], 'a') {'a': 3} >>> max_([], default=-1) -1 .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return max(_iterator_with_default(collection, default), key=pyd.iteratee(callback))
def sort_by(collection, iteratee=None, reverse=False): """Creates a list of elements, sorted in ascending order by the results of running each element in a `collection` through the iteratee. Args: collection (list|dict): Collection to iterate over. iteratee (mixed, optional): Iteratee applied per iteration. reverse (bool, optional): Whether to reverse the sort. Defaults to ``False``. Returns: list: Sorted list. Example: >>> sort_by({'a': 2, 'b': 3, 'c': 1}) [1, 2, 3] >>> sort_by({'a': 2, 'b': 3, 'c': 1}, reverse=True) [3, 2, 1] >>> sort_by([{'a': 2}, {'a': 3}, {'a': 1}], 'a') [{'a': 1}, {'a': 2}, {'a': 3}] .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return sorted(collection, key=pyd.iteratee(iteratee), reverse=reverse)
def itercallback(obj, callback=None, reverse=False): """Return iterative callback based on collection type.""" cbk = pyd.iteratee(callback) items = iterator(obj) if reverse: items = reversed(tuple(items)) for key, item in items: yield (call_callback(cbk, item, key, obj), item, key, obj)
def iteriteratee(obj, iteratee=None, reverse=False): """Return iterative iteratee based on collection type.""" cbk = pyd.iteratee(iteratee) items = iterator(obj) if reverse: items = reversed(tuple(items)) # Precompute argcount to avoid repeated calculations during iteratee loop. argcount = getargcount(cbk, maxargs=3) for key, item in items: yield (callit(cbk, item, key, obj, argcount=argcount), item, key, obj)
def iteriteratee(obj, iteratee=None, reverse=False): """Return iterative iteratee based on collection type.""" if iteratee is None: cbk = pyd.identity argcount = 1 else: cbk = pyd.iteratee(iteratee) argcount = getargcount(cbk, maxargs=3) items = iterator(obj) if reverse: items = reversed(tuple(items)) for key, item in items: yield (callit(cbk, item, key, obj, argcount=argcount), item, key, obj)
def itercallback(obj, callback=None, reverse=False): """Return iterative callback based on collection type.""" cbk = pyd.iteratee(callback) items = iterator(obj) if reverse: items = reversed(tuple(items)) # Precompute argcount to avoid repeated calculations during callback loop. argcount = getargcount(cbk, maxargs=3) for key, item in items: yield (callit(cbk, item, key, obj, argcount=argcount), item, key, obj)
def every(collection, callback=None): """Checks if the callback returns a truthy value for all elements of a collection. The callback is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for callback, the created :func:`pluck` style callback will return the property value of the given element. If an object is passed for callback, the created :func:`where` style callback will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: bool: Whether all elements are truthy. Example: >>> every([1, True, 'hello']) True >>> every([1, False, 'hello']) False >>> every([{'a': 1}, {'a': True}, {'a': 'hello'}], 'a') True >>> every([{'a': 1}, {'a': False}, {'a': 'hello'}], 'a') False >>> every([{'a': 1}, {'a': 1}], {'a': 1}) True >>> every([{'a': 1}, {'a': 2}], {'a': 1}) False See Also: - :func:`every` (main definition) - :func:`all_` (alias) .. versionadded:: 1.0.0 """ if callback: cbk = pyd.iteratee(callback) collection = [cbk(item) for item in collection] return all(collection)
def every(collection, predicate=None): """Checks if the predicate returns a truthy value for all elements of a collection. The predicate is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for predicate, the created :func:`pluck` style predicate will return the property value of the given element. If an object is passed for predicate, the created :func:`.matches` style predicate will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. predicate (mixed, optional): Predicate applied per iteration. Returns: bool: Whether all elements are truthy. Example: >>> every([1, True, 'hello']) True >>> every([1, False, 'hello']) False >>> every([{'a': 1}, {'a': True}, {'a': 'hello'}], 'a') True >>> every([{'a': 1}, {'a': False}, {'a': 'hello'}], 'a') False >>> every([{'a': 1}, {'a': 1}], {'a': 1}) True >>> every([{'a': 1}, {'a': 2}], {'a': 1}) False .. versionadded:: 1.0.0 .. versionchanged: 4.0.0 Removed alias ``all_``. """ if predicate: cbk = pyd.iteratee(predicate) collection = (cbk(item) for item in collection) return all(collection)
def every(collection, predicate=None): """Checks if the predicate returns a truthy value for all elements of a collection. The predicate is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for predicate, the created :func:`pluck` style predicate will return the property value of the given element. If an object is passed for predicate, the created :func:`where` style predicate will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. predicate (mixed, optional): Predicate applied per iteration. Returns: bool: Whether all elements are truthy. Example: >>> every([1, True, 'hello']) True >>> every([1, False, 'hello']) False >>> every([{'a': 1}, {'a': True}, {'a': 'hello'}], 'a') True >>> every([{'a': 1}, {'a': False}, {'a': 'hello'}], 'a') False >>> every([{'a': 1}, {'a': 1}], {'a': 1}) True >>> every([{'a': 1}, {'a': 2}], {'a': 1}) False .. versionadded:: 1.0.0 .. versionchanged: TOOD Removed alias ``all_``. """ if predicate: cbk = pyd.iteratee(predicate) collection = [cbk(item) for item in collection] return all(collection)
def invert_by(obj, iteratee=None): """ This method is like :func:`invert` except that the inverted object is generated from the results of running each element of object thru iteratee. The corresponding inverted value of each inverted key is a list of keys responsible for generating the inverted value. The iteratee is invoked with one argument: ``(value)``. Args: obj (dict): Object to invert. iteratee (mixed): Iteratee applied per iteration. Returns: dict: Inverted dict. Example: >>> obj = {'a': 1, 'b': 2, 'c': 1} >>> results = invert_by(obj) # {1: ['a', 'c'], 2: ['b']} >>> set(results[1]) == set(['a', 'c']) True >>> set(results[2]) == set(['b']) True >>> results2 = invert_by(obj, lambda value: 'group' + str(value)) >>> results2['group1'] == results[1] True >>> results2['group2'] == results[2] True Note: Assumes `obj` values are hashable as ``dict`` keys. .. versionadded:: 4.0.0 """ callback = pyd.iteratee(iteratee) result = {} for key, value in iterator(obj): result.setdefault(callback(value), []).append(key) return result
def uniq(array, callback=None): """Creates a duplicate-value-free version of the array. If callback is passed, each element of array is passed through a callback before uniqueness is computed. The callback is invoked with three arguments: ``(value, index, array)``. If a property name is passed for callback, the created :func:`pydash.collections.pluck` style callback will return the property value of the given element. If an object is passed for callback, the created :func:`pydash.collections.where` style callback will return ``True`` for elements that have the properties of the given object, else ``False``. Args: array (list): List to process. callback (mixed, optional): Callback applied per iteration. Returns: list: Unique list. Example: >>> uniq([1, 2, 3, 1, 2, 3]) [1, 2, 3] See Also: - :func:`uniq` (main definition) - :func:`unique` (alias) .. versionadded:: 1.0.0 """ if callback: cbk = pyd.iteratee(callback) computed = [cbk(item) for item in array] else: computed = array # NOTE: Using array[i] instead of item since callback could have modified # returned item values. lst = [array[i] for i, _ in iterunique(computed)] return lst
def some(collection, callback=None): """Checks if the callback returns a truthy value for any element of a collection. The callback is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for callback, the created :func:`pluck` style callback will return the property value of the given element. If an object is passed for callback, the created :func:`where` style callback will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. callbacked (mixed, optional): Callback applied per iteration. Returns: bool: Whether any of the elements are truthy. Example: >>> some([False, True, 0]) True >>> some([False, 0, None]) False >>> some([1, 2, 3, 4], lambda x: x >= 3) True >>> some([1, 2, 3, 4], lambda x: x == 0) False See Also: - :func:`some` (main definition) - :func:`any_` (alias) .. versionadded:: 1.0.0 """ if callback: cbk = pyd.iteratee(callback) collection = [cbk(item) for item in collection] return any(collection)
def invert_by(obj, iteratee=None): """This method is like :func:`invert` except that the inverted object is generated from the results of running each element of object thru iteratee. The corresponding inverted value of each inverted key is a list of keys responsible for generating the inverted value. The iteratee is invoked with one argument: ``(value)``. Args: obj (dict): Object to invert. Returns: dict: Inverted dict. Example: >>> obj = {'a': 1, 'b': 2, 'c': 1} >>> results = invert_by(obj) # {1: ['a', 'c'], 2: ['b']} >>> set(results[1]) == set(['a', 'c']) True >>> set(results[2]) == set(['b']) True >>> results2 = invert_by(obj, lambda value: 'group' + str(value)) >>> results2['group1'] == results[1] True >>> results2['group2'] == results[2] True Note: Assumes `obj` values are hashable as ``dict`` keys. .. versionadded:: 4.0.0 """ callback = pyd.iteratee(iteratee) result = {} for key, value in iterator(obj): result.setdefault(callback(value), []).append(key) return result
def some(collection, predicate=None): """Checks if the predicate returns a truthy value for any element of a collection. The predicate is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for predicate, the created :func:`map_` style predicate will return the property value of the given element. If an object is passed for predicate, the created :func:`where` style predicate will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. predicateed (mixed, optional): Predicate applied per iteration. Returns: bool: Whether any of the elements are truthy. Example: >>> some([False, True, 0]) True >>> some([False, 0, None]) False >>> some([1, 2, 3, 4], lambda x: x >= 3) True >>> some([1, 2, 3, 4], lambda x: x == 0) False .. versionadded:: 1.0.0 .. versionchanged:: 4.0.0 Removed alias ``any_``. """ if predicate: cbk = pyd.iteratee(predicate) collection = [cbk(item) for item in collection] return any(collection)
def max_(collection, callback=None): """Retrieves the maximum value of a `collection`. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: mixed: Maximum value. Example: >>> max_([1, 2, 3, 4]) 4 >>> max_([{'a': 1}, {'a': 2}, {'a': 3}], 'a') {'a': 3} .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return max(collection, key=pyd.iteratee(callback))
def min_(collection, callback=None): """Retrieves the minimum value of a `collection`. Args: collection (list|dict): Collection to iterate over. callback (mixed, optional): Callback applied per iteration. Returns: mixed: Minimum value. Example: >>> min_([1, 2, 3, 4]) 1 >>> min_([{'a': 1}, {'a': 2}, {'a': 3}], 'a') {'a': 1} .. versionadded:: 1.0.0 """ if isinstance(collection, dict): collection = collection.values() return min(collection, key=pyd.iteratee(callback))
def some(collection, predicate=None): """Checks if the predicate returns a truthy value for any element of a collection. The predicate is invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed for predicate, the created :func:`map_` style predicate will return the property value of the given element. If an object is passed for predicate, the created :func:`.matches` style predicate will return ``True`` for elements that have the properties of the given object, else ``False``. Args: collection (list|dict): Collection to iterate over. predicateed (mixed, optional): Predicate applied per iteration. Returns: bool: Whether any of the elements are truthy. Example: >>> some([False, True, 0]) True >>> some([False, 0, None]) False >>> some([1, 2, 3, 4], lambda x: x >= 3) True >>> some([1, 2, 3, 4], lambda x: x == 0) False .. versionadded:: 1.0.0 .. versionchanged:: 4.0.0 Removed alias ``any_``. """ if predicate: cbk = pyd.iteratee(predicate) collection = (cbk(item) for item in collection) return any(collection)
def duplicates(array, callback=None): """Creates a unique list of duplicate values from `array`. If callback is passed, each element of array is passed through a callback before duplicates are computed. The callback is invoked with three arguments: ``(value, index, array)``. If a property name is passed for callback, the created :func:`pydash.collections.pluck` style callback will return the property value of the given element. If an object is passed for callback, the created :func:`pydash.collections.where` style callback will return ``True`` for elements that have the properties of the given object, else ``False``. Args: array (list): List to process. callback (mixed, optional): Callback applied per iteration. Returns: list: List of duplicates. Example: >>> duplicates([0, 1, 3, 2, 3, 1]) [3, 1] .. versionadded:: 3.0.0 """ if callback: cbk = pyd.iteratee(callback) computed = [cbk(item) for item in array] else: computed = array # NOTE: Using array[i] instead of item since callback could have modified # returned item values. lst = uniq([array[i] for i, _ in iterduplicates(computed)]) return lst
import pydash print(pydash.chain([4, 2, 3, 4]).sort().initial().value()) print(pydash.count_substr("reorieorieo", 'ri')) print(pydash.iteratee('a.b.c')({"a": {"b": {"c": 1}}})) def tee(obj, path): if not path: return obj h, *t = path if not isinstance(obj, dict): return if not obj.get(h): return return tee(obj[h], t) def iter_path(s): h, *rest = s.split('.', maxsplit=1) if not rest: yield h, None else: yield h, iter_path(rest[0]) def iter_path2(ss): s = 0 for i, ch in enumerate(ss): if ss[i] == '.':
def test_iteratee(case, arg, expected): getter = _.iteratee(case) assert _.map_(arg, getter) == expected