转换字典键和键的最快方法python3中从`bytes`到`str`的​​值

时间:2015-10-15 00:10:44

标签: python if-statement

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

CREATE FUNCTION dbo.LastCharIndex(@searchStr NVARCHAR(10), 
                                  @string NVARCHAR(MAX))
    RETURNS INT
AS
BEGIN
    DECLARE @idx INT = 0
    WHILE CHARINDEX(@searchStr, @string, @idx + 1) > 0
        SET @idx = CHARINDEX(@searchStr, @string, @idx + 1)

    RETURN @idx
END

似乎我对从py2移植到py3的库使用了很多。

是否有人为同一任务设计了更好的设计?这个可以优化吗?

3 个答案:

答案 0 :(得分:16)

不知道速度的优化,但我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

答案 1 :(得分:7)

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

答案 2 :(得分:5)

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

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