예제 #1
0
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))
예제 #2
0
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))
예제 #3
0
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_))
예제 #4
0
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_)))
예제 #5
0
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))
예제 #6
0
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_)))
예제 #7
0
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_))
예제 #8
0
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_))
예제 #9
0
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_))
예제 #10
0
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))
예제 #11
0
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_)))
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
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
예제 #15
0
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)
예제 #16
0
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_)))