Python:更新具有占位符的字典字符串?

问题描述

请考虑以下字符串:"{'a': A,'b': B,'c': 10}"。现在,我想更新此“字符串”并添加新的密钥d,并说值20,因此结果将是"{'a': A,'c': 10,'d': 20}"

通常,您可以将字符串(evalliteral_eval)评估为字典,更新所需的方式,然后将其转换回字符串。但是在这种情况下,存在占位符,在进行评估时不会被识别。

什么是最好的更新方式,因此旧值保持不变,但“ dict-string”已正确更新?

解决方法

对于可以正确解析字典的更健壮的解决方案,您可以将lib2to3.refactor.RefactoringTool子类化,使用lib2to3.fixer_base.BaseFix子类的修复程序来重构代码,该修复程序具有寻找{{1}的模式}节点,以及一种dictsetmaker方法,该方法用叶子节点扩展了transform列表,该叶子节点由将在dict中构成新键值对的令牌组成:

children

这将输出:

from lib2to3 import fixer_base,refactor,pytree
from lib2to3.pgen2 import token

class AddKeyValue(fixer_base.BaseFix):
    PATTERN = "dictsetmaker"

    def transform(self,node,results):
        node.children.extend((
            pytree.Leaf(token.COMMA,','),pytree.Leaf(token.STRING,"'d'",prefix=' '),pytree.Leaf(token.COLON,':'),pytree.Leaf(token.NUMBER,20,prefix=' ')
        ))
        return node

class Refactor(refactor.RefactoringTool):
    def __init__(self,fixers):
        self._fixers= [cls(None,None) for cls in fixers]
        super().__init__(None)

    def get_fixers(self):
        return self._fixers,[]

s = "{'a': A,'b': B,'c': 10}"
print(Refactor([AddKeyValue]).refactor_string(s + '\n',''))

{'a': A,'c': 10,'d': 20} 是往返稳定的,因此转换后所有空白都将保留,如果要在其前面插入空白,则应使用lib2to3指定一个新节点。

您可以在prefix模块的Grammar.txt中找到Python语法的定义。

演示:https://repl.it/@blhsing/RudeLimegreenConcentrate

,

我认为您可以:

选项1-添加

在字符串末尾的“}”之前插入新的字符串“,key:value”。

选项2-RagEx用于添加/更新

1-使用find()并搜索密钥。如果存在,请使用正则表达式替换:

re.replace(regex_search,regex_replace,contents)

因此,使用类似的内容:

string = re.sub(r'key: (.+),'key: value',article)

2-如果find()失败,请使用选项1的加法

,

如果只是要在字符串末尾添加...

this_string = "{'a': A,'c': 10}"
this_add = "'d': 20"
this_string = f"{this_string[:-1]},{this_add}{this_string[-1]}"
print(this_string)

将输出

{'a': A,'d': 20}

如果您需要在两者之间插入新字符串,则可以使用string.find进行类似操作,以找到索引并改用该索引号。

基本上是重写整个字符串,但是字符串是不变的,我们该怎么办。

,

这绝不是最好的解决方案,但这是一种方法:

FlyoutItem

输出:

@client.event
async def on_member_join(member):
    roles = {"Level": 705112591927869513,"Interests": 705116168444444773,"Region": 725984087948656710,"Subscriptions": 705122149152850062}
    
    member_role = discord.utils.get(member.guild.roles,name = "member")
    await member.add_roles(member_role)
    for role in roles.keys():
        newrole = discord.utils.get(member.guild.roles,id = roles[role])
        await member.add_roles(newrole)
    await member.send("Welcome to the server! Please read the rules and verify yourself to be able to type! "
"Link to jump directly to the message - link")
import re

dict_str = "{'a': A,'c': 10}"

def update_dict(dict_str,**keyvals):
    """creates an updated dict_str

        Parameters:
            dict_str (str): current dict_str
            **keyvals: variable amounts of key-values

        Returns:
            str:updated string

    """
    new_entries = ",".join(map(lambda keyval: f"'{keyval[0]}': {keyval[1]}",keyvals.items())) # create a string representation for each key-value and join by ','
    return dict_str.replace("}",f",{new_entries}{'}'}")   # update the dict_str by removing the last '}' and add the new entries

updated = update_dict(dict_str,d = 20,e = 30
)
print(updated)
{'a': A,'d': 20,'e': 30}