0

Example - I have a dict like this:

{b'mykey': {b'inner_key': b'inner_value'}}

How can I convert it to a dict where strings and values are all strings?

sjakobi
  • 3,546
  • 1
  • 25
  • 43
ignoring_gravity
  • 6,677
  • 4
  • 32
  • 65

4 Answers4

1
def decode_dict(d, encoding_used = 'utf-8'):
    return { k.decode(encoding_used) : (v.decode(encoding_used) if isinstance(v, bytes) else decode_dict(v, encoding_used)) for k, v in d.items() }

new_dict = decode_dict({b'mykey': {b'inner_key': b'inner_value'}})
print(new_dict)

If your encoding is not UTF-8, you need to use the second argument in the call.

Błotosmętek
  • 12,717
  • 19
  • 29
0

Use decode:

b'somestring'.decode('utf-8')
Darina
  • 1,488
  • 8
  • 17
  • And to do it for your dict, you can use something like this, where `d` is the dictionary you posted `decoded = {key.decode("utf-8"): {k.decode("utf-8"): v.decode("utf-8") for (k, v) in value.items()} for (key, value) in d.items()}` For more information: https://stackoverflow.com/questions/606191/convert-bytes-to-a-string – afterburner Jun 05 '20 at 13:57
0

With a simple dictionary like {b'inner_key': b'inner_value'} you could do something like this:

for k, v in list(d.items()):
    d[k.decode('utf8')] = d.pop(k).decode('utf8')

This needs to be extended to more general cases in which there could be nested dictionaries. However it modifies the dictionary inplace, which could be useful if you do not want to create another dictionary.

Riccardo Bucco
  • 13,980
  • 4
  • 22
  • 50
0

I ended up doing

def _convert_bytes_dict(data):
    out = {}
    for key, val in data.items():
        if isinstance(val, list):
            decoded_val = [_convert_bytes_dict(i) for i in val]
        elif not hasattr(val, "items") and not hasattr(val, "decode"):
            decoded_val = val
        elif not hasattr(val, "items"):
            decoded_val = val.decode("utf-8")
        else:
            decoded_val = _convert_bytes_dict(val)
        out[key.decode("utf-8")] = decoded_val
    return out
ignoring_gravity
  • 6,677
  • 4
  • 32
  • 65