如何将字典的键和值从字节转换为字符串?

How to convert key and value of dictionary from byte to string?

我有编码格式的字典。可以有嵌套的字典,我不知道它可以嵌套多少。

数据样本如下所示

 1:{
      b'key1':{
         b'key11':2022,
         b'key12':1,
         b'key13':2022,
         b'key32':1,
         b'key14':b'x86\xe3\x88',
         b'key21':b'U_001776',
         b'key34':b'\xe6\xb4\xbe\xe9\x81\xa3\xe7\xa4\xbe\xe5\x93\xa1',
         b'key65':b'U_001506',
         b'key45':b'\xbc',
         b'key98':b'1\x81\x88'b'kwy66':{
            b'keyq':b'sometext'
         }
      }
   },

将其转换为字符串 我试过这个


def convert_dict(data):
    if isinstance(data,str):
        return data
    elif isinstance(data,bytes):
        return data.decode()
    elif isinstance(data,dict):
        for key,val in data.items():
            if isinstance(key,bytes):
                data[key.decode()] = convert_dict(data[key])
            else:
                data[key] = convert_dict(data[key])
        return data
    elif isinstance(data,list):
        temp_list = []
        for dt in data:
            temp_list.append(convert_dict(dt))
        return temp_list
    else:
        return data

我收到 dictionary changed size during iteration。这有什么错误吗?请帮忙。

编辑 1.

数据实际上是在 php 中序列化的,我不得不使用 python 来反序列化。 我用 This 在字典中转换它。

from phpserialize import *
temp = loads(serialized_data.encode())

我收到了字典,但它的键和值都被编码了。我不得不使用 serialized_data.encode() 因为加载将接受字节数据类型。 我将此温度传递给 convert_dict 函数。

您不能在迭代时修改 dict 中的键集(在迭代时基本上修改 any 集合是不安全的,但是 dicts,不像其他一些,需要做一些 self-checking 来避免 崩溃 如果你违反了那个规则,所以当他们在做的时候,他们会提出一个异常而不是默默地做一些古怪的事情)。因此,构建一个新的 dict 和 return 而不是:

def convert_dict(data):
    if isinstance(data,str):
        return data
    elif isinstance(data,bytes):
        return data.decode()
    elif isinstance(data,dict):
        newdata = {}  # Build a new dict
        for key, val in data.items():
            # Simplify code path by just doing decoding in conditional, insertion unconditional
            if isinstance(key,bytes):
                key = key.decode()
            newdata[key] = convert_dict(val)  # Update new dict (and use the val since items() gives it for free)
        return newdata
    elif isinstance(data,list):
        return [convert_dict(dt) for dt in data]
    else:
        return data

为了好玩,我做了一些小修改以减少代码重复,因此大部分工作都是通过公共路径完成的,并演示了使用 listcomp 简化 list 案例。

您无法更改正在迭代的字典。最好return一个新的结构:

def convert(d):
    if isinstance(d, dict):
        return {convert(k): convert(v) for k, v in d.items()}
    if isinstance(d, list):
        return [convert(i) for i in d]
    if isinstance(d, bytes):
        return d.decode()
    return d