在python3中将字典的键值从`bytes`转换为`str`的最快方法
问题描述:
python2 here的优秀示例。我的翻译python3(如下所示)适用于我所有的测试。在python3中将字典的键值从`bytes`转换为`str`的最快方法
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的库。
有没有人对同一项任务有更好的设计?这个可以优化吗?
答
不知道关于优化速度,但我不的范式if/return/else
的忠实粉丝,因为它(这里没有这样的问题)堵塞了不必要的东西的代码,并导致了语言压痕楼梯没有elif
。
优化可读性(这通常是我的第一选择),我把所有这些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
+0
这样一个简单的改变,在可读性方面有了如此巨大的改进 –
答
扩展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))
答
最简单的方法是使用字典解析如下:
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}}
>>>
什么是错的这一个? – salparadise
“更好的设计模式” - 哦..这是什么样的设计模式? :/ –