Fastest way to convert dict keys and values ​​from `unicode` to` str`?

I get a dict from one “layer” of code on which some calculations / modifications are performed before passing it to another “layer”. The original dict keys and string values ​​are unicode , but the layer to which they are passed takes only str .

This will often be triggered, so I would like to know what would be the fastest way to convert something like:

 { u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } } 

... at:

 { 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } } 

... taking into account that values ​​other than the "string" should remain as their original type.

Any thoughts?

+65
python casting types
Aug 10 '09 at 11:51
source share
6 answers
 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'} 

Assumptions:

  • You have imported the collections module and can use the abstract base classes that it provides.
  • You can convert using the default encoding (use data.encode('utf-8') , not str(data) if you need an explicit encoding).

If you need to support other types of containers, we hope that it will be obvious how to follow the pattern and add cases to them.

+129
Aug 10 '09 at 12:03
source share

I know I'm late for this one:

 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()) 
+19
Aug 11 2018-11-11T00:
source share

If you want to do this inline and don't need a recursive descent, this might work:

 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 } }" 
+12
Jul 18 2018-11-11T00:
source share
 def to_str(key, value): if isinstance(key, unicode): key = str(key) if isinstance(value, unicode): value = str(value) return key, value 

pass the key and value to it and add recursion to your code to account for the internal dictionary.

+3
Aug 10 '09 at 11:59
source share

for a non-nested dict (since the name does not mention this case, this may be interesting for other people)

 {str(k): str(v) for k, v in my_dict.items()} 
+2
Jul 20 '16 at 8:45
source share

To make everything inline (non-recursive):

 {str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()} 
+2
Apr 04 '17 at 15:34 on
source share



All Articles