2015-10-15 16 views
7

Ví dụ tuyệt vời cho python2 here. Bản dịch của tôi sang python3 (được hiển thị bên dưới) hoạt động trong tất cả các thử nghiệm của tôi.Cách nhanh nhất để chuyển đổi khóa và giá trị của dict từ `byte` thành` str` trong 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 

Dường như tôi đang sử dụng rất nhiều thư viện đã được chuyển từ py2 sang py3.

Có ai có thiết kế tốt hơn cho cùng một tác vụ không? Điều này có thể được tối ưu hóa không?

+1

Điều gì là sai với điều này? – salparadise

+0

"mẫu thiết kế tốt hơn" - oh .. loại mô hình thiết kế này là gì? :/ –

Trả lời

9

Không biết về tối ưu hóa cho tốc độ nhưng tôi không một fan hâm mộ lớn của if/return/else mô hình vì nó bịt kín lên mã với những thứ không cần thiết và gây ra cầu thang thụt đầu dòng cho các ngôn ngữ mà không elif (không phải là một vấn đề như vậy ở đây) .

Tối ưu hóa cho dễ đọc (mà thường là ưu tiên đầu tiên của tôi), tôi muốn biến tất cả những elif dòng vào if và mương else hoàn toàn, định dạng lại để làm cho nó nhỏ gọn hơn:

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

Sự thay đổi đơn giản như vậy cho sự cải thiện lớn về khả năng đọc –

2

Mở rộng của paxdiablo câu trả lời để xử lý nhiều trường hợp sử dụng hơn dẫn đến các trường hợp sau:

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)) 

Rõ ràng là việc áp dụng chức năng bản đồ là khá nhất quán và chúng ta có thể khái quát hóa nó.

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

Cách đơn giản nhất là nên sử dụng sự hiểu biết từ điển như sau:

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

Ví dụ:

>>> 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'} 
>>> 

Để chuyển đổi các cặp giá trị phím kiểu byte trong thứ tự ngẫu nhiên, sử dụng :

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

Ví dụ:

>>> 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'} 
>>> 

Lưu ý: Đoạn mã trên sẽ tốt hơn cho dữ liệu từ điển đơn giản. Nhưng đối với các từ điển phức tạp, tôi muốn sử dụng mã Guy Gangemi 's mà là một sửa đổi của paxdiablo's câu trả lời:

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 

Ví dụ:

>>> 
>>> 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}} 
>>> 
Các vấn đề liên quan