将字典的键和值从“unicode”转换为“str”的最快方法?
我从一个“层”代码接收字典,在执行一些计算/修改之前,将其传递到另一个“层”上。 原始字典的键和“string”值是unicode
,但它们传递到的层只接受str
。
这将被称为经常,所以我想知道什么是最快的方式来转换类似的东西:
{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }
…至:
{ 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } }
…铭记非“串”值需要保持原来的types。
有什么想法吗?
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'}
假设:
- 您已经导入了集合模块,并可以使用它提供的抽象基类
- 你很乐意使用默认的编码(如果你需要一个明确的编码,使用
data.encode('utf-8')
而不是str(data)
)。
如果你需要支持其他的容器types,希望能够明白如何遵循这个模式并为它们添加案例。
我知道我迟到了:
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())
如果你想这样做内联,并不需要recursion下降,这可能会工作:
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 } }"
def to_str(key, value): if isinstance(key, unicode): key = str(key) if isinstance(value, unicode): value = str(value) return key, value
将密钥和值传递给它,并将recursion添加到您的代码来说明内部字典。
对于一个非嵌套的字典(因为标题没有提到这种情况下,其他人可能会感兴趣)
{str(k): str(v) for k, v in my_dict.items()}
使其全部内联(非recursion):
{str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()}