MiniMe
MiniMe

Reputation: 1275

Dictionary with regular expressions as keys in Python

import re
collections ={}
collections [re.compile ('n.*')]='word that starts with n'

I expect collections ['never'] to return 'word that starts with n' but the above is not happening.

What I am doing wrong?

Upvotes: 0

Views: 5290

Answers (2)

Eric Duminil
Eric Duminil

Reputation: 54223

Solution

No magic is happening here, so you'll have to iterate on every pair :

import re
collections = {}
collections[re.compile('n.*')] = 'word that starts with n'
collections[re.compile(r'\b....\b')] = '4 letter word'


def find_matching_regexen(word, dicts=collections):
    return [description for regex, description in dicts.items() if regex.match(word)]

print(find_matching_regexen('never'))
# ['word that starts with n']
print(find_matching_regexen('boat'))
# ['4 letter word']
print(find_matching_regexen('nice'))
# ['word that starts with n', '4 letter word']
print(find_matching_regexen('dog'))
# []

If the output order is important, you would have to use an OrderedDict

Note

From the zen of python :

Explicit is better than implicit.

If you want to achieve something in Python, you usually have to write it. The syntax might be short and clear, but it still needs to be written explicitely.

So no, a string will not be considered as having the same hash as a matching regex in a dict.

If you're looking for some more magic, you might take a look at Ruby. It has a broader definition of patterns, which can be classes, regexen or strings :

[1, "abc", 2, "def"].grep(/a/)
# => ["abc"]
[1, "abc", 2, "def"].grep(Integer)
# => [1, 2]

Patterns are also used in case statements. As an example, you can match a string with a regex without conversion or explicit method call:

def find_matching_regexen(word)
  case word
  when /^n.*/
    "Word that starts with n"
  when /\b....\b/
    "4 letter word"
  end
end

puts find_matching_regexen("boat")
# "4 letter word"
puts find_matching_regexen("nice")
# "Word that starts with n"
puts find_matching_regexen("dog")
# nil

Upvotes: 5

Zealseeker
Zealseeker

Reputation: 823

def collections(text):
  if re.compile('n.*').findall(text):
    return 'word that starts with n'
print collections('never')
>>> word that starts with n

Upvotes: -1

Related Questions