【问题标题】:Best way to .replace() all instances of a String in a dictionary.replace() 字典中字符串的所有实例的最佳方法
【发布时间】:2021-12-14 10:28:29
【问题描述】:

在 python 中,我从数据库中收到以下数据结构:

{
  "field":"Somestring/somestring.jpg?<<TOKEN>>",
  "list": [
     {"field": "sometring.html?<<TOKEN>>"},
     {"field2": "otherstring.mp4?<<TOKEN>>"}
   ]
}

而且这个结构很可能会被扩展以包含更多带有字段的列表。

我希望将出现在整个数据结构中不同字符串中的“>”的所有实例替换为其他用于访问这些字符串所代表的 url 的验证令牌。

有没有更好的方法来做到这一点,而不是使用循环访问每个字段,检查其是否为字符串,然后运行:field.replace("&lt;&lt;TOKEN&gt;&gt;", my_token)

【问题讨论】:

  • 你能把整个json 加载为字符串,然后在上面加上replace() 吗?

标签: python python-3.x dictionary for-loop data-structures


【解决方案1】:

递归方法

这就像一个步行者,进入数据结构的每一层并应用处理正确类型的治疗。 这让您也可以处理特殊情况或特定数据类型。

var = {
  "field":"Somestring/somestring.jpg?<<TOKEN>>",
  "list": [
     {"field": "sometring.html?<<TOKEN>>"},
     {"field2": "otherstring.mp4?<<TOKEN>>"}
   ]
}

def replacer(obj, val:str):
    if isinstance(obj, str):
        return obj.replace('<<TOKEN>>', val)
    
    if isinstance(obj, list):
        return [replacer(x,val) for x in obj]
    
    if isinstance(obj, dict):
        return {k:replacer(x,val) for k,x in obj.items()}
    
    # other cases
    #if ...
    return obj

    
    
replacer(var, 'ciao')

#{'field': 'Somestring/somestring.jpg?ciao',
# 'list': [{'field': 'sometring.html?ciao'},
#  {'field2': 'otherstring.mp4?ciao'}]}

使用序列化程序

正如@Mahrkeenerh 所说(赞) 这是一个技巧,json-fied 版本也是一个字符串,因此执行单个替换的效果更好。

序列化 -> 治愈 -> 反序列化

import json
json.loads(json.dumps(var).replace('<<TOKEN>>', 'ciao'))

#{'field': 'Somestring/somestring.jpg?ciao',
# 'list': [{'field': 'sometring.html?ciao'},
#  {'field2': 'otherstring.mp4?ciao'}]}

【讨论】:

  • 这非常有效。我决定采用递归方法,因为数据结构将被扩展以包含不同的对象等,而这种优雅的解决方案可以解决所有这些问题。
猜你喜欢
  • 2016-08-31
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 1970-01-01
  • 2019-06-17
相关资源
最近更新 更多