Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a regular expression be used as a key in a dictionary?

Tags:

I want to create a dictionary where the keys are regular expressions:

d = {'a.*': some_value1, 'b.*': some_value2}

Then, when I look into the dictionary:

d['apple']

I want apple 'apple' to be matched against the keys which are regular expressions. If there is a complete match with a key/regular-expression then the corresponding value should be returned.

For example 'apple' matches with the regular expression 'a.*' completely, and so, some_value1 should be returned.

Of course, all of this assumes that the regular expression keys do not conflict (i.e. two keys should not both match the same string exactly). Let's say I can manually take care of this requirement when building my keys.

Is this possible in Python? If so, it would be quite an elegant and powerful construct!

like image 695
applecider Avatar asked Oct 26 '15 10:10

applecider


People also ask

What can be used as a key in a dictionary?

Second, a dictionary key must be of a type that is immutable. For example, you can use an integer, float, string, or Boolean as a dictionary key. However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable.

What Cannot be used as a key in a dictionary?

We can use integer, string, tuples as dictionary keys but cannot use list as a key of it .

Can a dictionary have a set as a key?

Yes. According to the docs, Frozenset is hashable because it's immutable. This would imply that it can be used as the key to a dict, because the prerequisite for a key is that it is hashable.

Can we use string as key in dictionary?

The dictionary webstersDict used strings as keys in the dictionary, but dictionary keys can be any immutable data type (numbers, strings, tuples etc). Dictionary values can be just about anything (int, lists, functions, strings, etc).


1 Answers

Python dictionaries are implemented as hash tables - which means any mydict[myvalue] lookup is very fast by internally hashing myvalue. Using regular expressions as keys will cancel this functionality. Instead of using a dictionary, you should use a simple list or tuple where each item is a tuple in the format: (pattern/compiled regular expression, value) and scan them until a regular expression passes. This will also give you the ability to play with the order of regular expressions (from specific to general, for example):

import re

LOOKUPS  = [
    ('a.*', 'a'),
    ('b.*', 'b'),
]

def lookup(s, lookups):
    for pattern, value in lookups:
        if re.search(pattern, s):
            return value
    return None

print(lookup("apple", LOOKUPS))

See also Django's url resolver for a (very) advanced implementation of your idea.

like image 68
Udi Avatar answered Sep 20 '22 22:09

Udi