The dict dictionary is fast and very easy to use. If you want to search for a key with a regular expression, you would normally do this, but if you use it a lot, it's a hassle.
a = dict(abc=1, def=2) #-> {"abc": 1, "def": 2}
s = re.compile(".bc")
ret = []
for k in a:
    if s.search(k):
        ret.append(a[k])
print(ret) #-> [1]
#It looks like this at best even if it is shortened by the inclusion notation, but it is not readable and I do not know what I wanted to do when I read the source when I forgot.
s = re.compile(".bc")
[a[k] for k in a if s.search(k)] #-> [1]
Since this is troublesome, I extended the standard dict so that it can be used like this.
a = rdict(abc=1, def=2) #-> {"abc": 1, "def": 2}
a.search(".bc") #-> [1]
The source is like this.
import re
from functools import lru_cache
@lru_cache(16) # re.Since compile is a fairly heavy process, the same regular expression pattern is cached to gain performance.
def re_call(pattern, flags=0, call_re_func="search"):
    return re.compile(pattern, flags=flags).__getattribute__(call_re_func)
class rdict(dict):
    def _filter(self, _callable):
        return (k for k in self if _callable(k))
    def isin(self, key_or_function):
        if callable(key_or_function):
            return any(True for _ in self._filter(key_or_function))
        return dict.__contains__(self, key_or_function)
    def findall(self, key_or_function):
        if callable(key_or_function):
            return [dict.__getitem__(self, key) for key in self._filter(key_or_function)]
        return dict.__getitem__(self, key_or_function)
    def search(self, pattern, flags=0):
        return [dict.__getitem__(self,key) for key in self if re_call(pattern, flags, "search")(key)]
    def fullmatch(self, pattern, flags=0):
        return [dict.__getitem__(self,key) for key in self if re_call(pattern, flags, "fullmatch")(key)]
    def __setitem__(self, key_or_function, value):
        if callable(key_or_function):
            for key in self._filter(key_or_function):
                dict.__setitem__(self, key, value)
        else:
            return dict.__setitem__(self, key_or_function, value)
    def __delitem__(self, key_or_function):
        if callable(key_or_function):
            for key in list(self._filter(key_or_function)):
                dict.__delitem__(self, key)
        else:
            return dict.__delitem__(self, key_or_function)
I've added some other functions, but here's an image of how to use them.
Find out if there is a matching key in the regular expression pattern
    >>> a.isin(re.compile(".b.*").search)
    True
    >>> a.isin(re.compile(".z.*").search)
    False
Other 1. Returns the value when having a key when the condition is true.
    >>> a.findall(lambda x: len(x) == 3)
    [1, 2]
Other 2. Search the key in the range and return the value If the argument of findall is callable, anything works, so the following applications are also possible
    >>> from datetime import datetime
    >>> b = funcdict()
    >>> b[datetime(2020,1,1)] = "2020/01/01"
    >>> b[datetime(2020,2,1)] = "2020/02/01"
    >>> b[datetime(2020,3,1)] = "2020/03/01"
    >>> def between_0131_0202(x):
    ...    return datetime(2020,1,31) < x and x < datetime(2020,2,2)
    >>> b.findall(between_0131_0202)
    ['2020/02/01']
    >>> def less_0401(x):
    ...    return x < datetime(2020, 4, 1)
    >>> b.isin(less_0401)
    True
    >>> def grater_0401(x):
    ...    return x > datetime(2020, 4, 1)
    >>> b.isin(grater_0401)
    False
    >>> b.findall(less_0401)
    ['2020/01/01', '2020/02/01', '2020/03/01']
After that, the function to change the value of the key that matches the condition at once
    >>> b[less_0401] = "test"
    >>> b
    {datetime.datetime(2020, 1, 1, 0, 0): 'test',
     datetime.datetime(2020, 2, 1, 0, 0): 'test',
     datetime.datetime(2020, 3, 1, 0, 0): 'test'}
By the way, the function to delete all the keys that match the conditions at once
    >>> del b[between_0131_0202]
    >>> b
    {datetime.datetime(2020, 1, 1, 0, 0): 'test',
     datetime.datetime(2020, 3, 1, 0, 0): 'test'}
        Recommended Posts