Reputation: 11
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
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
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
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
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