【问题标题】:Replace a string to a value in dict using Python使用 Python 将字符串替换为 dict 中的值
【发布时间】:2018-04-25 11:56:20
【问题描述】:

假设我有一个字典列表

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

我有一个句子“PHONE is STATUS”。我想将句子中的关键字替换为字典中的值。所以输出应该是

111 忙 122 忙 133是免费的

由于 STATUS 匹配字典中的键,所以我可以使用 re 来替换它,

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

但是模式 PHONE 与字典中的键 TELEPHONE 不同,有没有类似的方法来做这样的替换?我不想更改字典中的键。我可以做类似“如果我遇到“PHONE”,然后我使用字典中的“TELEPHONE”键检索?”

【问题讨论】:

  • 您可以在字典中将 TELEPHONE 更改为 PHONE,然后将新字典与 PHONE 和 STATUS 一起使用。
  • 我不明白字符串“PHONE is STATUS”在哪里起作用。您的输出可以仅从字典列表中生成。能详细点吗?
  • 假设您的字典列表名为dicts,您可以尝试以下操作:sentence = "TELEPHONE is STATUS"; " ".join(" ".join(d.get(y) if y in d else y for y in sentence.split()) for d in dicts)
  • 抱歉不清楚。问题是有许多不同的模式。一种可能是“PHONE is STATUS”,也可能是“PHONE 的状态是 STATUS”。我必须按照模式,一一更换。
  • " ".join(" ".join(d.get(y) if y in d else y for y in sentence.replace('PHONE', 'TELEPHONE').split()) for d in dicts)PHONE 替换为 TELEPHONE 并执行我之前的评论打算执行的操作。

标签: python dictionary string-matching


【解决方案1】:

我会创建一个备用键字典,因此如果未找到 PHONE,它会在字典中查找我们无法更改的对应键,使用带有默认值的链式 get 调用。我会在每个单词上应用它并重建句子

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()))

结果:

111 is BUSY
122 is BUSY
133 is FREE

这种方法的优点是没有线性查找。问题是get都执行了,可以用or短路解决:

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

现在如果wd 中,它不会计算表达式的第二部分。

【讨论】:

    【解决方案2】:

    你可以试试这个:

    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])
    

    输出:

    '111 is BUSY 122 is BUSY 133 is FREE'
    

    【讨论】:

    • 谢谢。这个看起来像匹配键的子字符串?有没有其他方式可以将“COST”匹配到“PRICE”,而不是“PHONE”匹配“TELEPHONE”?
    • @WillN.Walker 我相信您刚刚发布的附加匹配超出了问题的范围。请发布您必须与“COST”和“PRICE”相关的输入和字典
    • 例如,dict 可以是 [{'ITEM': 'APPLE', 'PRICE': '100'}, {'ITEM': 'BANANA', 'PRICE': '50' }],模式为“ITEM 的成本为 COST”。结果应该是“APPLE 的成本是 100”,“香蕉的成本是 50”。我想在 dict 中使用 PRICE 作为 COST 一词进行查找。
    • @WillN.Walker 这更像是一个自然语言处理问题。您必须声明一个键为“PRICE”的字典,并拥有一个相关值列表,例如“COST”、“VALUE”或“MONEY”。
    【解决方案3】:

    很难说出您要完成什么,但我认为您有一个电话列表并且正在获取日志消息以更新其状态。试试这个:

    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')
    

    【讨论】:

      【解决方案4】:

      试试这个:

      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]))
      

      【讨论】:

      • 当我在 IDLE (Python 3.6.3 Shell) 中尝试时,它说“语法无效”
      猜你喜欢
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      相关资源
      最近更新 更多