def filterkeys(predicate, dict_): """Return a new dictionary comprising of keys for which ``predicate`` returns True, and their corresponding values. :param predicate: Predicate taking a dictionary key, or None """ predicate = bool if predicate is None else ensure_callable(predicate) ensure_mapping(dict_) return dict_.__class__((k, v) for k, v in iteritems(dict_) if predicate(k))
def filtervalues(predicate, dict_): """Returns a new dictionary comprising of values for which ``predicate`` return True, and keys that corresponded to them. :param predicate: Predicate taking a dictionary value, or None """ predicate = bool if predicate is None else ensure_callable(predicate) ensure_mapping(dict_) return dict_.__class__((k, v) for k, v in iteritems(dict_) if predicate(v))
def mapvalues(function, dict_): """Return a new dictionary where the values come from applying ``function`` to the values of given dictionary. :param function: Function taking a dictionary value, or None (corresponding to identity function) .. versionadded:: 0.0.2 """ ensure_mapping(dict_) function = identity() if function is None else ensure_callable(function) return dict_.__class__((k, function(v)) for k, v in iteritems(dict_))
def filteritems(predicate, dict_): """Return a new dictionary comprising of items for which ``predicate`` returns True. :param predicate: Predicate taking a key-value pair, or None .. versionchanged: 0.0.2 ``predicate`` is now taking a key-value pair as a single argument. """ predicate = all if predicate is None else ensure_callable(predicate) ensure_mapping(dict_) return dict_.__class__(ifilter(predicate, iteritems(dict_)))
def extend(dict_, *dicts, **kwargs): """Extend a dictionary with keys and values from other dictionaries. :param dict_: Dictionary to extend Optional keyword arguments allow to control the exact way in which ``dict_`` will be extended. :param overwrite: Whether repeated keys should have their values overwritten, retaining the last value, as per given order of dictionaries. This is the default behavior (equivalent to ``overwrite=True``). If ``overwrite=False``, repeated keys are simply ignored. Example:: >> foo = {'a': 1} >> extend(foo, {'a': 10, 'b': 2}, overwrite=True) {'a': 10, 'b': 2} >> foo = {'a': 1} >> extend(foo, {'a': 10, 'b': 2}, overwrite=False) {'a': 1, 'b': 2} :param deep: Whether extending should proceed recursively, and cause corresponding subdictionaries to be merged into each other. By default, this does not happen (equivalent to ``deep=False``). Example:: >> foo = {'a': {'b': 1}} >> extend(foo, {'a': {'c': 2}}, deep=False) {'a': {'c': 2}} >> foo = {'a': {'b': 1}} >> extend(foo, {'a': {'c': 2}}, deep=True) {'a': {'b': 1, 'c': 2}} :return: Extended ``dict_`` .. versionadded:: 0.0.2 """ ensure_mapping(dict_) dicts = list(imap(ensure_mapping, dicts)) ensure_keyword_args(kwargs, optional=('deep', 'overwrite')) return _nary_dict_update([dict_] + dicts, copy=False, deep=kwargs.get('deep', False), overwrite=kwargs.get('overwrite', True))
def invert(dict_): """Return an inverted dictionary, where former values are keys and former keys are values. .. warning:: If more than one key maps to any given value in input dictionary, it is undefined which one will be chosen for the result. :param dict_: Dictionary to swap keys and values in :return: Inverted dictionary """ ensure_mapping(dict_) return dict_.__class__(izip(itervalues(dict_), iterkeys(dict_)))
def peekvalue(dict_): """Return some value from the dictionary without modifying it. :param dict_: Dictionary to retrieve the value from :return: Value from ``dict_`` :raise KeyError: If the dictionary is empty .. versionadded:: 0.0.4 """ ensure_mapping(dict_) if not dict_: raise KeyError("peekvalue(): dictionary is empty") return next(itervalues(dict_))
def peekitem(dict_): """Return some item from the dictionary without modifying it. :param dict_: Dictionary to retrieve the item from :return: Pair of ``(key, value)`` from ``dict_`` :raise KeyError: If the dictionary is empty .. versionadded:: 0.0.3 """ ensure_mapping(dict_) if not dict_: raise KeyError("peekitem(): dictionary is empty") return next(iteritems(dict_))
def mapkeys(function, dict_): """Return a new dictionary where the keys come from applying ``function`` to the keys of given dictionary. .. warning:: If ``function`` returns the same value for more than one key, it is undefined which key will be chosen for the resulting dictionary. :param function: Function taking a dictionary key, or None (corresponding to identity function) .. versionadded:: 0.0.2 """ ensure_mapping(dict_) function = identity() if function is None else ensure_callable(function) return dict_.__class__((function(k), v) for k, v in iteritems(dict_))
def starfilteritems(predicate, dict_): """Return a new dictionary comprising of keys and values for which ``predicate`` returns True. :param predicate: Predicate taking key and value, or None .. versionchanged:: 0.0.2 Renamed ``starfilteritems`` for consistency with :func:`starmapitems`. """ ensure_mapping(dict_) if predicate is None: predicate = lambda k, v: all((k, v)) else: ensure_callable(predicate) return dict_.__class__( (k, v) for k, v in iteritems(dict_) if predicate(k, v))
def mapitems(function, dict_): """Return a new dictionary where the keys and values come from applying ``function`` to key-value pairs from given dictionary. .. warning:: If ``function`` returns a key-value pair with the same key more than once, it is undefined which value will be chosen for that key in the resulting dictionary. :param function: Function taking a key-value pair as a single argument, and returning a new key-value pair; or None (corresponding to identity function) .. versionadded:: 0.0.2 """ ensure_mapping(dict_) function = identity() if function is None else ensure_callable(function) return dict_.__class__(imap(function, iteritems(dict_)))
def select(keys, from_, strict=False): """Selects a subset of given dictionary, including only the specified keys. :param keys: Iterable of keys to include :param strict: Whether ``keys`` are required to exist in the dictionary. :return: Dictionary whose keys are a subset of given ``keys`` :raise KeyError: If ``strict`` is True and one of ``keys`` is not found in the dictionary. """ ensure_iterable(keys) ensure_mapping(from_) if strict: return from_.__class__((k, from_[k]) for k in keys) else: existing_keys = set(keys) & set(iterkeys(from_)) return from_.__class__((k, from_[k]) for k in existing_keys)
def get(dict_, keys=(), default=None): """Extensions of standard :meth:`dict.get`. Retrieves an item from given dictionary, trying given keys in order. :param dict_: Dictionary to perform the lookup(s) in :param keys: Iterable of keys :param default: Default value to return if no key is found :return: Value for one of given ``keys``, or ``default`` """ ensure_mapping(dict_) ensure_iterable(keys) for key in keys: try: return dict_[key] except KeyError: pass return default
def ensure_keyword_args(kwargs, mandatory=(), optional=()): """Checks whether dictionary of keyword arguments satisfies conditions. :param kwargs: Dictionary of keyword arguments, received via ``*kwargs`` :param mandatory: Iterable of mandatory argument names :param optional: Iterable of optional argument names :return: ``kwargs`` if the conditions are met: all ``mandatory`` arguments are present, and besides that no arguments outside of ``optional`` ones are. :raise TypeError: When conditions are not met """ from taipan.strings import ensure_string ensure_mapping(kwargs) mandatory = list(map(ensure_string, ensure_iterable(mandatory))) optional = list(map(ensure_string, ensure_iterable(optional))) if not (mandatory or optional): raise ValueError( "mandatory and/or optional argument names must be provided") names = set(kwargs) for name in mandatory: try: names.remove(name) except KeyError: raise TypeError( "no value for mandatory keyword argument '%s'" % name) excess = names - set(optional) if excess: if len(excess) == 1: raise TypeError("unexpected keyword argument '%s'" % excess.pop()) else: raise TypeError( "unexpected keyword arguments: %s" % (tuple(excess),)) return kwargs
def omit(keys, from_, strict=False): """Returns a subset of given dictionary, omitting specified keys. :param keys: Iterable of keys to exclude :param strict: Whether ``keys`` are required to exist in the dictionary :return: Dictionary filtered by omitting ``keys`` :raise KeyError: If ``strict`` is True and one of ``keys`` is not found in the dictionary .. versionadded:: 0.0.2 """ ensure_iterable(keys) ensure_mapping(from_) if strict: remaining_keys = set(iterkeys(from_)) remove_subset(remaining_keys, keys) # raises KeyError if necessary else: remaining_keys = set(iterkeys(from_)) - set(keys) return from_.__class__((k, from_[k]) for k in remaining_keys)
def starmapitems(function, dict_): """Return a new dictionary where the keys and values come from applying ``function`` to the keys and values of given dictionary. .. warning:: If ``function`` returns a key-value pair with the same key more than once, it is undefined which value will be chosen for that key in the resulting dictionary. :param function: Function taking key and value as two arguments and returning a new key-value pair, or None (corresponding to identity function) .. versionadded:: 0.0.2 """ ensure_mapping(dict_) if function is None: function = lambda k, v: (k, v) else: ensure_callable(function) return dict_.__class__(starmap(function, iteritems(dict_)))