Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python, accessing dictionary with wildcards

I have a dictionary with items, where the keys are some kind of regular expressions. I am looking for a function to return a list of matching items whenever a matching string is passed

d = {'a.b': item1, 'b.c':item2}

func(d,'a1b')
>>> [item1]

func(d,'b2c')
>>> [item2]

Is there a pythonic way to do this ? The only solution I can come up with is:

import re
def func(d, event):
    res = list()
    for key, item in d.iteritems():
        if re.match(key, event):
            res.append(item)
    return res
like image 263
greole Avatar asked Jan 09 '14 15:01

greole


2 Answers

You can create a class that will do that for you that wraps the dictionary class:

import re

class RegexDict(dict):

    def get_matching(self, event):
        return (self[key] for key in self if re.match(key, event))

Example of use:

>>> d = {'a.b': 'item1', 'b.c': 'item2'}
>>> rd = RegexDict(d)
>>> for o in rd.get_matching('a1b'):
    print o


item1

This saves you having to rely on external functions, it keeps the overhead small, and is more robust.

You could also add another function that takes a list (or iter) as input and returns all matching values:

    def get_all_matching(self, events):
        return (match for event in events for match in self.get_matching(event))

>>> for o in rd.get_all_matching(['a1b', 'b2c']):
    print o


item1
item2
like image 88
Inbar Rose Avatar answered Oct 31 '22 19:10

Inbar Rose


You don't need to loop over the values. Just the key is enough:

import re
def func(d, event):
    res = []
    for key in d.keys():
        if re.match(key, event):
            res.append(d[key])
    return res

Here is a generator version. This one is faster because it doesn't store the whole list, but only generate it when needed:

def func(d, event):
    for key in d.keys():
        if re.match(key, event):
            yield d[key]

And a one liner:

#1 List Comprehension
return [d[key] for key in d.keys() if re.match(key, event)]
#2 Generator Expression
return (d[key] for key in d.keys() if re.match(key, event))
like image 30
aIKid Avatar answered Oct 31 '22 21:10

aIKid