2015-10-15 250 views
7

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的庫。

有沒有人對同一項任務有更好的設計?這個可以優化嗎?

+1

什麼是錯的這一個? – salparadise

+0

「更好的設計模式」 - 哦..這是什麼樣的設計模式? :/ –

回答

9

不知道關於優化速度,但我不範式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

這樣一個簡單的改變,在可讀性方面有了如此巨大的改進 –

2

擴展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)) 
1

最簡單的方法是使用字典解析如下:

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}} 
>>> 
相關問題