将字典的键和值从“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()}