Will N. Walker
Will N. Walker

Reputation: 11

Replace a string to a value in dict using Python

Suppose I have a list of dictionary

    [{'TELEPHONE': '111', 'STATUS': 'BUSY'}, {'TELEPHONE': '122', 'STATUS': 'BUSY'}, 
    {'TELEPHONE': '133', 'STATUS': 'FREE'}]

and I have a sentence "PHONE is STATUS". I want to replace the keyword from the sentence to the values in the dictionary. So the output should be

111 is BUSY 122 is BUSY 133 is FREE

Since STATUS matches the key in the dictionary, so I can use re to replace it,

    pattern = re.compile(r'\b(' + '|'.join(val.keys()) + r')\b')
    result = pattern.sub(lambda x: val[x.group()], text)

but the pattern PHONE is different to the key TELEPHONE in the dictionary, is there a similar way to do such replacement? I don't want to change the keys in the dictionary. Can I do something like "if I meet "PHONE", then I retrieve using the key "TELEPHONE" in the dict?"

Upvotes: 1

Views: 1072

Answers (4)

Ajax1234
Ajax1234

Reputation: 71451

You can try this:

import re
sentence = "PHONE is STATUS"
keys = re.findall('[A-Z]+', sentence)
s = [{'TELEPHONE': '111', 'STATUS': 'BUSY'}, {'TELEPHONE': '122', 'STATUS': 'BUSY'}, {'TELEPHONE': '133', 'STATUS': 'FREE'}]
final_data = ' '.join([' is '.join([[b for a, b in i.items() if a.endswith(keys[0])][0], i[keys[-1]]]) for i in s])

Output:

'111 is BUSY 122 is BUSY 133 is FREE'

Upvotes: 1

Serg Anuke
Serg Anuke

Reputation: 168

Try this:

l = [{'TELEPHONE': '111', 'STATUS': 'BUSY'}, {'TELEPHONE': '122', 'STATUS': 'BUSY'}, {'TELEPHONE': '133', 'STATUS': 'FREE'}]
print("".join(["{} is {}".format(
    i['TELEPHONE'], i['status']) for i in l]))

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140186

I would create a fallback key dictionary, so if PHONE isn't found, it looks for a corresponding key in the dict that we cannot change, using chained get calls with default values. I'd apply that on each word & rebuild the sentence

dl = [{'TELEPHONE': '111', 'STATUS': 'BUSY'}, {'TELEPHONE': '122', 'STATUS': 'BUSY'},
    {'TELEPHONE': '133', 'STATUS': 'FREE'}]

# synonyms dict, you can add as many as you want
mk = {"PHONE" : "TELEPHONE", "STATE" : "STATUS"}


for d in dl:
    print(" ".join(d.get(w,d.get(mk.get(w),w)) for w in "PHONE is STATUS".split()))

result:

111 is BUSY
122 is BUSY
133 is FREE

the advantage of this method is that there's no linear lookup. The problem is that both get are performed, which can be solved with a or short circuit:

print(" ".join(d.get(w) or d.get(mk.get(w),w) for w in "PHONE is STATUS".split()))

now if w is in d, it doesn't evaluate the second part of the expression.

Upvotes: 1

soundstripe
soundstripe

Reputation: 1474

Hard to tell what you're trying to accomplish but I think you have a phone list and are getting log messages to update their status. Try this:

import re

status_update = '111 is BUSY'
status_re = re.compile('(\d+) is ([A-Z]+)')

phone, new_status = status_re.match(status_update).groups()
found = False
for val in phone_list:
    if phone == val['TELEPHONE']:
        val['STATUS'] = new_status
        found = True
if not Found:
    print('phone not found')
else:
    print('phone status updated')

Upvotes: 0

Related Questions