【问题标题】:Convert a string with components separated by symbols into a nested python dictionary将具有由符号分隔的组件的字符串转换为嵌套的python字典
【发布时间】:2025-12-26 08:55:07
【问题描述】:

我正在为一个 Python 问题而苦苦挣扎,希望能提供任何帮助。请耐心等待,我的 Python 目前是基本的。


问题:

如何转换这样的字符串结构:

text="key1=value1;key2=value2\nkeyA=valueA\n..."

像这样进入 Python 字典:

{0:{'key1':'value1', 'key2':'value2'}, 1:{'keyA':'valueA'}}
  1. 意识到';'分隔内部字典中的项目,而'\n' 分隔外部字典中的项目。
  2. 内部字典中的键、值是字符串。外部字典的键是索引。

需要有另一个函数来将此 Python 字典转换回其原始字符串形式。


我现在在哪里:

我正在考虑创建一个能够执行此操作的循环,但我正在努力创建它。

         a[0]["key1"]="value1"  
         a[0]["key2"]="value2"  
         a[1]["keyA"]="valueA"  

我做的最好的就是用 '\n' 分割字符串,如下所示:

text ='k1=v1;k2=v2\nk3=v3\nk4=v4'
text = text.split("\n")

output: ['k1=v1;k2=v2', 'k3=v3', 'k4=v4']

并像这样将元素循环到字典中:

dic = {}
for i,x in enumerate(text):
    dic[i] = x

output: {0: 'k1=v1;k2=v2', 1: 'k3=v3', 2: 'k4=v4'}

但是如何将字典中的这些值放入键、值结构中,如上所示?

【问题讨论】:

    标签: string python-3.x dictionary


    【解决方案1】:

    您可以使用以下字典理解:

    {i: dict(p.split('=', 1) for p in l.split(';')) for i, l in enumerate(text.split('\n')) if l}
    

    使用您的示例输入:

    text="key1=value1;key2=value2\nkeyA=valueA\n"
    

    这会返回:

    {0: {'key1': 'value1', 'key2': 'value2'}, 1: {'keyA': 'valueA'}}
    

    【讨论】:

    • 我羡慕你有 10k+ 代表以最少冗长的代码进来
    • 很高兴能提供帮助。 '\n'.join(';'.join('='.join(i) for i in s.items()) for s in d.values()) 可以,给定一个字典d。如果您认为此答案正确,您能否将其标记为已接受? (点击答案旁边的灰色复选标记。)
    • @blhsing 感谢您的及时回复。 (1)您有没有办法将这个过程从字典中反转回原始文本? (2) 我意识到您在代码末尾使用了“if l”。我尝试在没有它的情况下运行代码,它工作正常。 '如果我'是必要的吗? PS:我删除了之前的评论以添加第二点。感谢您的时间。
    • 如果您的字符串以\n 结尾,我的答案中的if l 是必需的,在这种情况下split('\n') 将返回一个列表,其中最后一项是'',这不是我们要处理。您是否尝试过我上面评论中的反转代码?它对你有用吗?
    • 反转完美。我仍然没有得到if l 部分。您能否解释为什么仅通过添加 if l 就排除了 ' ' ?谢谢。
    【解决方案2】:

    可能有一种更简洁、更精确的方法来解决您的问题,但目前,您可以使用这个来解决。

    def make_dict(string):
        temp={}
        string=string.split(';')
        string=[i.split('=') for i in string]
        for a,b in string:
            temp[a]=b 
        return temp 
    
    text ='k1=v1;k2=v2\nk3=v3\nk4=v4'
    text=text.split('\n')
    dic={}
    
    for i,x in enumerate(text):
        dic[i] = make_dict(x)
    
    >>> print(dic) 
    >>> {0: {'k1': 'v1', 'k2': 'v2'}, 1: {'k3': 'v3'}, 2: {'k4': 'v4'}}
    

    如果你想扭转上述过程,那么可以通过以下方式完成。

    def convert_again(dct):
        fetch_values = list(dct.values())
    
        change_values_to_list = [list(i.items()) for i in fetch_values]
    
        # add "=" in between the key-value pairs 
        for i in range(len(change_values_to_list)):
            for j in range(len(change_values_to_list[i])):
                change_values_to_list[i][j]='='.join(change_values_to_list[i][j])
    
        # Now add ";"
        answer = [';'.join(i) for i in change_values_to_list]
        # Now add "\n" 
        final_answer = '\\n'.join(answer)
        return final_answer
    
        #Driver Code
    
        dct= {0: {'k1': 'v1', 'k2': 'v2'}, 1: {'k3': 'v3'}, 2: {'k4': 'v4'}}
        print(convert_again(dct)) # --> "k1=v1;k2=v2\nk3=v3\nk4=v4"
    

    【讨论】:

    • @匿名感谢您抽出宝贵时间回答这个问题。作为一个新手 python 用户,我发现你的解释比@blhsing 更直观。您是否有一种方法可以将这个过程从字典中反转回原始文本?希望收到您的来信。
    • 我已经相应地编辑了我的答案。我希望它有所帮助。 :)
    【解决方案3】:

    我已经编写了一个解决方案,它也可以扩展到其他示例。 我创建了一个更复杂的示例

    注意,我们还有另一个由; 分隔的集合。如果我可以在这个例子中演示它,它也应该适用于其他人

    请务必注意,这仅在 text 中的最后 2 个字符为 "\n" 时才有效。如果最后两个字符中没有"\n",则删除list1.remove("")这一行

    text="key3=value3;key4=value4\nkey1=value1;key2=value2\nkeyA=valueA\nkeyB=valueB\n"
    

    我首先被\n 拆分,这意味着列表中会有一个"",因为text 的最后两个字符是“\n”

    list1 = text.split("\n")
    list1.remove("") 
    

    现在我正在创建两个列表,一个用于附加由";" 分隔的字符串,另一个用于附加未被";" 分隔的字符串

    list2 = [] #Stuff seperated by ;
    list3 = [] #Stuff not seperated by ;
    
    for items in list1:
    
        if ';' in items:
            list2.append(items)
    
        else:
            list3.append(items)
    

    我创建了一个空字典,最终有你想要的:

    result_dict = {} #To store all key, value pairs
    

    list2 现在有['key3=value3;key4=value4', 'key1=value1;key2=value2']

    #First storing key, value pairs seperated by ";"
    for i in range(0, len(list2)):
        a = list2[i].split(";")
        result_dict[i] = dict(s.split('=') for s in a)
    

    list3 拥有['keyA=valueA', 'keyB=valueB']

    #Now storing key, value pairs not seperated by ";"
    nosemicolon_dict = dict(s.split('=') for s in list3)
    
    for key, value in nosemicolon_dict.items():
        for j in range(0, len(nosemicolon_dict)):
            result_dict[j + i + 1] = {key:value}
    

    对于您的示例,运行上面相同的代码,将text 替换为您的示例,同时确保考虑"\n" 是否是您示例中的最后两个字符。如果字符串末尾没有"\n",请删除list1.remove("") THIS LINE

    print(result_dict)
    

    给了我:

    {0: {'key1': 'value1', 'key2': 'value2'}, 1: {'keyA': 'valueA'}}
    

    【讨论】: