Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove dictionary values based on regex?

I have the following dictionary in Python

dict1 = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88, "key333": 12, "key3X": 13}

I want to delete keys that do not follow the pattern "xxx#" or "xxx##". That is, three characters followed by a one-digit integer or a two-digit integer. Using the above example, this is:

new_dict = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88}

For one or two keys, the way I would create a new dictionary would be with a list comprehension:

small_dict = {k:v for k,v in your_dic.items() if v not in ["key333", "key3X"]}

However, how would I use regex/other string methods to remove these strings?

Separate question: What if there's a special exception, e.g. one key I would like to key called "helloXX"?

like image 507
ShanZhengYang Avatar asked Aug 29 '26 14:08

ShanZhengYang


2 Answers

This should match all the keys in your example as well as your exception case:

new_dict = {k:dict1[k] for k in dict1 if re.match('[^\d\s]+\d{1,2}$', k)}

Using a new example dict with your exception in it:

>>> dict1 = {"key1": 2345, "key2": 356, "key3": 773, "key44": 88, "key333": 12, "key3X": 13, "hello13": 435, "hello4325": 345, "3hi33":3}
>>> new_dict = {k:dict1[k] for k in dict1 if re.match('[^\d\s]+\d{1,2}$', k)}
>>> print(new_dict)
{'hello13': 435, 'key44': 88, 'key3': 773, 'key2': 356, 'key1': 2345}
like image 78
Billy Avatar answered Aug 31 '26 05:08

Billy


You can use a regex to match 3 letters, followed by one or two digits, followed directly by the end of the string ($):

>>> import re
>>> small_dict = {k:v for k,v in dict1.items() if re.match('[a-z]{3}\d{1,2}$',k, re.IGNORECASE)}
>>> small_dict
{'key44': 88, 'key3': 773, 'key1': 2345, 'key2': 356}

Note that re.match searches for the regex at the beginning of the string : "123key123" wouldn't match for example.

If there are exceptions, you could add them after having filtered the keys. If you want to do it in one go:

small_dict = {k:v for k,v in dict1.items() if re.match('[a-z]{3}\d{1,2}$',k, re.IGNORECASE) or k in ["hello12", "hello34"]}
like image 37
Eric Duminil Avatar answered Aug 31 '26 03:08

Eric Duminil