【问题标题】:Fastest way to convert a dict's keys & values from `bytes` to `str` in python3在python3中将字典的键和值从`bytes`转换为`str`的​​最快方法
【发布时间】:2016-01-13 06:34:47
【问题描述】:

python2 here 的优秀示例。我对 python3 的翻译(如下所示)适用于我的所有测试。

def convert(data):
    if isinstance(data, bytes):
        return data.decode('ascii')
    elif isinstance(data, dict):
        return dict(map(convert, data.items()))
    elif isinstance(data, tuple):
        return map(convert, data)
    else:
        return data

似乎我经常将它用于已从 py2 移植到 py3 的库。

对于相同的任务,有人有更好的设计吗?这个可以优化吗?

【问题讨论】:

  • 这个有什么问题?
  • “更好的设计模式” - 哦..这是什么设计模式? ://
  • 只是想知道,哪个操作首先给了你字节?我认为应该根据结果本身调整原点...很多组件都有标志,可以根据需要为您提供结果...

标签: python if-statement


【解决方案1】:

不知道速度优化,但我 不是 if/return/else 范式的忠实粉丝,因为它会用不必要的东西堵塞代码,并导致没有 @987654322 的语言缩进楼梯@(这里不是这样的问题)。

优化可读性(这通常是我的首选),我会将所有elif 行转换为if 并完全放弃else,重新格式化以使其更紧凑:

def convert(data):
    if isinstance(data, bytes):  return data.decode('ascii')
    if isinstance(data, dict):   return dict(map(convert, data.items()))
    if isinstance(data, tuple):  return map(convert, data)
    return data

【讨论】:

  • 这样一个简单的改动就可以大大提高可读性
【解决方案2】:

最简单的方法是使用字典理解,如下所示:

new_data = { key.decode(): val.decode() for key, val in data.items() }

示例:

>>> data = {
...   b'cart1': b'apples',
...   b'cart2': b'oranges',
...   b'cart3': b'grapes'
... }
>>> 
>>> new_data = { key.decode(): val.decode() for key, val in data.items() }
>>> 
>>> new_data
{'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes'}
>>>

要以随机顺序转换类型字节的键值对,请使用:

new_data = {
    key.decode() if isinstance(key, bytes) else key:
    val.decode() if isinstance(val, bytes) else val
    for key, val in data.items()
}

示例:

>>> data = {
...   b'cart1': 'apples',
...   'cart2': b'oranges',
...   b'cart3': b'grapes'
... }
>>> 
>>> new_data = {
...     key.decode() if isinstance(key, bytes) else key:
...     val.decode() if isinstance(val, bytes) else val
...     for key, val in data.items()
... }
>>> new_data
{'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes'}
>>>

注意:以上代码更适合简单的数据字典。但是对于复杂的字典,我更喜欢使用Guy Gangemi的代码,它是paxdiablo's的修改答案:

def convert(data):
    if isinstance(data, bytes):  return data.decode()
    if isinstance(data, dict):   return dict(map(convert, data.items()))
    if isinstance(data, tuple):  return tuple(map(convert, data))
    if isinstance(data, list):   return list(map(convert, data))
    return data

例子:

>>> 
>>> def convert(data):
...     if isinstance(data, bytes):  return data.decode()
...     if isinstance(data, dict):   return dict(map(convert, data.items()))
...     if isinstance(data, tuple):  return tuple(map(convert, data))
...     if isinstance(data, list):   return list(map(convert, data))
...     return data
...
>>>
>>> data = {
...     b'fruits': {
...             b'cart1': b'apples',
...             b'cart2': 'oranges',
...             b'cart3': b'grapes',
...             b'cart4': (b'banana', 'pear'),
...             b'cart5': [b'kiwi', b'papaya']
...     },
...     'vegetables': {
...             'cart1': b'carrots',
...             b'cart2': None,
...             b'cart3': {},
...             b'cart4': False
...     }
... }
>>>
>>> convert(data)
{'fruits': {'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes', 'cart4': ('banana', 'pear'), 'cart5': ['kiwi', 'papaya']}, 'vegetables': {'cart1': 'carrots', 'cart2': None, 'cart3': {}, 'cart4': False}}
>>>

【讨论】:

    【解决方案3】:

    扩展 paxdiablo 的答案以处理更多用例导致以下结果:

    def convert(data):
      if isinstance(data, bytes):      return data.decode()
      if isinstance(data, (str, int)): return str(data)
      if isinstance(data, dict):       return dict(map(convert, data.items()))
      if isinstance(data, tuple):      return tuple(map(convert, data))
      if isinstance(data, list):       return list(map(convert, data))
      if isinstance(data, set):        return set(map(convert, data))
    

    很明显,map函数的应用是相当一致的,我们可以概括一下。

    def convert(data):
      data_type = type(data)
    
      if data_type == bytes: return data.decode()
      if data_type in (str, int): return str(data)
    
      if data_type == dict: data = data.items()
      return data_type(map(convert, data))
    

    【讨论】:

    • 为什么要将 str & int 转换为 str?似乎没有必要,而且通常是不可取的。
    猜你喜欢
    • 2010-11-18
    • 2016-10-04
    • 1970-01-01
    • 2014-08-03
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多