Dictionary that uses regular expressions

E

Erik Lechak

Hello all,

I wrote the code below. It is simply a dictionary that uses regular
expressions to match keys. A quick look at _test() will give you an
example.

Is there a module that already does this? Is there a way and would it
be better to use list comprehension? (using python 2.3)

Just looking for a better or more pythonic way to do it.

import re

class ReDict(dict):
'''
A dictionary that uses regular expressions keys

NOTE:
if the redict finds more than one key that matches the re it
returns a redict of all of the matching keys
'''
def __init__(self):
dict.__init__(self)
self.re=1

def reOn(self):
'''
turn regular expression matching on
'''
self.re=1

def reOff(self):
'''
turn regular expression matching off
'''
self.re=0

def __getitem__(self,key):
if self.re ==1:
temp = ReDict()
for item in self.items():
if re.search(key,item[0]): #line match
temp[item[0]]=item[1]

if len(temp)==1:
return temp.values()[0]

return temp
else:
return dict.__getitem__(self,key)


def _test():
d=ReDict()

d["price"]=7.25
d['call jan 5.0']=1
d['call jan 7.5']=1.5
d['put jan 7.5']=7.2

d['call feb 5.0']=2
d['call feb 7.5']=2.5
d['put feb 7.5']=6.8

d['call mar 5.0']=3
d['call mar 7.5']=3.5
d['put mar 7.5']=4

d['call apr 5.0']=4
d['call apr 7.5']=4.5
d['put apr 7.5']=6.2

d['call may 5.0']=5
d['call may 7.5']=5.5
d['put may 7.5']=4.9

print d['price'] #prints the price
print d['call']['may']['7.5'] # prints individual value
print d['call'] #returns a redict of all calls
print d['put'] #returns a redict of all puts
print d['may'] #returns a redict of all options in may

_test()


Thanks,
Erik Lechak
 
T

Terry Reedy

Erik Lechak said:
Hello all,

I wrote the code below. It is simply a dictionary that uses regular
expressions to match keys. A quick look at _test() will give you an
example.

Is there a module that already does this?

Not that I know of
Is there a way and would it
be better to use list comprehension? (using python 2.3)

List comp builds a list. Your __getitem__(s,key) code builds an
ReDict, not a list. If you extended your initializer to initialize
from a list of items (by passing the list of items on to
dict.__init__), then you could build such a list with a l.c. and
initialize your return ReDict from that. IE (untested, obviously, and
it's late...)

return ReDict( [item for item in self.items if
re.search(key,item[0]) ] )

If you were always (or even almost always) matching by re's, you might
as well just use a list of items (key,value). If you really must mix
normal and re retrieval, but only after the dict is built and stable,
then keeping items() as an attribute rather than re-extracting it for
each re access would be faster.

Terry J. Reedy
 
P

Peter Otten

I would leave the __getitem__() method alone and just add a
filterMatches(self, regexp) returning a ReDict or findMatches(self, regexp)
returning a list/iterator of values. That preserves the symmetry of

theDict[key] = value
value = theDict[key]

element access. It also makes client code more explicit as you can clearly
distinguish the reOn

x = theDict.filterMatches(bla)

and reOff

x = theDict[bla]

cases. Both reOn() and reOf() are no longer needed, plus you need not
overwrite __init__(), which preserves its expected (by users of dict)
behaviour.

Peter
 
J

Jack Diederich

Google may prove me wrong, but this looks like a new idea.



Try inheriting from UserDict.DictMixin instead of dict.

Some months ago I started rewriting the C regexps module to allow for
matching pure-python string types[1]. The python class would just have
to define a method to get the next character and optionally a method
to say how much to backtrack on a match failure. My use case was ternary
trees, instead of doing a lookup with a string key it would return
first or any matches of a regexp key.

Other people were doing heavy work on the regexp module so I'm waiting
for the 2.4 implementation to stabalize before I go back to it.

-jackdied

[1] http://mail.python.org/pipermail/python-dev/2003-April/034688.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top