user4737714
user4737714

Reputation:

Dictionary key in python are RegExp

I need to create a dictionary where the keys would be a regexp. I want to compare one value with different keys. For example, I want the same value for these keys:

int(1), int(2) ... int(10) 

and that is not for everyone to create keys, I need to have one regular expression for all possible keys. How can I do this?

Approximate example of dictionary:

dict = {'int([0-9]*)': 128, 'tinyint([0-9]*)': 64}

Can I do without cycles?

I check has not reached a limit value in the MYSQL. Limit for the field - always same. A type field may be int(1), int(2)...int(11)

I'm getting from MYSQL value to the type of the field in the tuple:

type_field = (u'number ', u'int (10)', u'NO ', u'PRI', None, u'auto_increment ')

And

>>> print type_field[1]

int (10)

I want to appeal directly to the value of the dictionary by key type_field[1], without a cycle. Like this:

di[type_field[1]]

With any number in int(number) from 1 to 11, I would receive the same value. Is it possible?

Upvotes: 2

Views: 432

Answers (4)

user4737714
user4737714

Reputation:

Thank for all. I did like this:

limits = {'tinyint': 127, 'tinyint unsigned': 255}
field_autoincrement = ('zxzxzxz', 'tinyint(4) unsigned', 'dsdsds')
limit = limits[re.compile('\(\d+\)').sub('', field_autoincrement[1])]
>>>limit
255

Upvotes: 0

dawg
dawg

Reputation: 103814

If you literally mean keys that are regex's, they are hashable objects in Python:

>>> {re.compile(r'int([0-9]*)'): 128}
{<_sre.SRE_Pattern object at 0x10cbd6200>: 128}

Which means you can do something like:

>>> di={re.compile(r'a'): 'ay in there', re.compile('b'): 'bees in there'}
>>> for s in ('say', 'what', 'you', 'mean', 'bag'):
...     print s, [di[k] for k in di if k.search(s)]
... 
say ['ay in there']
what ['ay in there']
you []
mean ['ay in there']
bag ['ay in there', 'bees in there']

Or just use the strings that represent the regex before it is used:

>>> di={r'^\w\w?a': '"a" is second or third letter' , r'^[^aeiou][aeiou]': "vowel after non-vowel"}
>>> for s in ('aaa', 'bag', 'box', 'drag'):
...     print s, [di[k] for k in di if re.search(k, s)]
... 
aaa ['"a" is second or third letter']
bag ['vowel after non-vowel', '"a" is second or third letter']
box ['vowel after non-vowel']
drag ['"a" is second or third letter']

Based on you update, it would seem to me that a list comprehension is what you are looking for:

li=[
(u'number ', u'int (10)', u'NO ', u'PRI', None, u'auto_increment '),
(u'number ', u'int (22)', u'NO ', u'PRI', None, u'auto_increment '),
(u'number ', u'int (11)', u'NO ', u'PRI', None, u'auto_increment '),
]

>>> [e for e in li if 1<int(re.search(r'\((\d+)\)$', str(e[1])).group(1))<11]
[(u'number ', u'int (10)', u'NO ', u'PRI', None, u'auto_increment ')]

Something other than that, you will probably need to create a class to do something more specialized. From what you are describing I think you still need to think through the details a bit more.

Upvotes: 2

Rcynic
Rcynic

Reputation: 392

regular expression patterns can be pre-compiled and stored anywhere you want.

so you create the pattern and store them as the key, and then your numerical output as the value.

import re

patt_dict = {
    re.compile('int\([0-9]*\)'): 128,
    re.compile('tinyint\([0-9]*\)'): 64
    }

now assuming you're reading a table create statement from a file

total_size = 0
with open('create_stmt.txt') as sql_fl:
    for line in sql_fl:
        for key, value in patt_dict.iteritems():
            if re.findall(key, line.strip()):
                total_size += value
print total_size

keep in mind that this is an O(n*m) algorithm. I'm not sure yet how to make it faster.

Upvotes: 0

Kasravnd
Kasravnd

Reputation: 107287

There is no need to use regex you can just use format within a dict comprehension :

{'int({})'.format(i):j for i,j in zip(range(1,len(val_list)+1),val_list)}

Example :

>>> val_list=['a','b','c','d']
>>> {'int({})'.format(i):j for i,j in zip(range(1,len(val_list)+1),val_list)}
{'int(1)': 'a', 'int(4)': 'd', 'int(2)': 'b', 'int(3)': 'c'}

Upvotes: 0

Related Questions