Je reçois un dict d'une "couche" de code sur laquelle des calculs/modifications sont effectués avant de le transmettre à une autre "couche". Les valeurs clés et "chaîne" du dict original sont unicode
, mais la couche sur laquelle elles sont transmises est uniquement compatible avec str
.
Cela va être appelé souvent, alors j'aimerais savoir quel serait le moyen le plus rapide de convertir quelque chose comme:
{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }
...à:
{ 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } }
... en gardant à l'esprit que les valeurs autres que "chaîne" doivent rester dans leur type d'origine.
Des pensées?
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'}
Hypothèses:
data.encode('utf-8')
plutôt que str(data)
si vous avez besoin d'un encodage explicite).Si vous avez besoin de prendre en charge d’autres types de conteneurs, nous espérons que la façon de suivre le modèle et d’ajouter des cas pour eux est évidente.
Je sais que je suis en retard sur celui-ci:
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())
Si vous voulez faire cela en ligne et que vous n'avez pas besoin de descente récursive, cela pourrait fonctionner:
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
transmettez la clé et la valeur, et ajoutez de la récursivité à votre code pour prendre en compte le dictionnaire interne.
pour un dict non imbriqué (puisque le titre ne mentionne pas ce cas, cela pourrait être intéressant pour d'autres personnes)
{str(k): str(v) for k, v in my_dict.items()}
Pour que tout soit en ligne (non récursif):
{str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()}