将dict的键和值从`unicode`转换为`str`的​​最快方法?

Phi*_*ham 77 python types casting

我从一个代码"层"接收一个字典,在将代码传递到另一个"层"之前执行一些计算/修改.原始字典的键和"字符串"值是unicode,但它们传递的层只接受str.

这将经常被调用,所以我想知道什么是最快的方式来转换像:

{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }
Run Code Online (Sandbox Code Playgroud)

...至:

{ 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } }
Run Code Online (Sandbox Code Playgroud)

...请记住,非"字符串"值需要保留为原始类型.

有什么想法吗?

Ric*_*dle 147

DATA = { u'spam': u'eggs', u'foo': frozenset([u'Gah!']), u'bar': { u'baz': 97 },
         u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])]}

def convert(data):
    if isinstance(data, basestring):
        return str(data)
    elif isinstance(data, collections.Mapping):
        return dict(map(convert, data.iteritems()))
    elif isinstance(data, collections.Iterable):
        return type(data)(map(convert, data))
    else:
        return data

print DATA
print convert(DATA)
# Prints:
# {u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])], u'foo': frozenset([u'Gah!']), u'bar': {u'baz': 97}, u'spam': u'eggs'}
# {'bar': {'baz': 97}, 'foo': frozenset(['Gah!']), 'list': ['list', (True, 'Maybe'), set(['and', 'a', 'set', 1])], 'spam': 'eggs'}
Run Code Online (Sandbox Code Playgroud)

假设:

  • 您已导入集合模块,并可以使用它提供的抽象基类
  • 您很乐意使用默认编码进行转换(使用data.encode('utf-8')而不是str(data)需要显式编码).

如果您需要支持其他容器类型,希望很明显如何遵循该模式并为它们添加案例.

  • @AbbasovAlexander:这样你就可以得到你输入的相同类型 - 一个元组成为一个元组,一个列表成为一个列表,一个集成为一个集合,依此类推. (4认同)
  • 为什么使用`type(data)(map(convert,data))`而不是`map(convert,data)`? (3认同)

Ger*_*ano 23

我知道我迟到了这个:

def convert_keys_to_string(dictionary):
    """Recursively converts dictionary keys to strings."""
    if not isinstance(dictionary, dict):
        return dictionary
    return dict((str(k), convert_keys_to_string(v)) 
        for k, v in dictionary.items())
Run Code Online (Sandbox Code Playgroud)


Sam*_*lay 12

如果你想内联并且不需要递归下降,这可能有效:

DATA = { u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }
print DATA
# "{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }"

STRING_DATA = dict([(str(k), v) for k, v in data.items()])
print STRING_DATA
# "{ 'spam': 'eggs', 'foo': True, 'bar': { u'baz': 97 } }"
Run Code Online (Sandbox Code Playgroud)

  • 对于2.7及以后,这可以简化如下:`{str(key):key的值,data.items()中的值} (4认同)