Python 转换dict的最快方法&x27;s键和;从'unicode'到'str'的值?
我从一个代码“层”接收到一个dict,在将其传递到另一个“层”之前,将在该dict上执行一些计算/修改。原始dict的键和“字符串”值是Python 转换dict的最快方法&x27;s键和;从'unicode'到'str'的值?,python,casting,types,Python,Casting,Types,我从一个代码“层”接收到一个dict,在将其传递到另一个“层”之前,将在该dict上执行一些计算/修改。原始dict的键和“字符串”值是unicode,但它们传递到的层只接受str 这将经常被调用,因此我想知道转换以下内容的最快方法: { u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } } …致: { 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } } …记住,非“字符串”值需要
unicode
,但它们传递到的层只接受str
这将经常被调用,因此我想知道转换以下内容的最快方法:
{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }
…致:
{ 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } }
…记住,非“字符串”值需要保持其原始类型
有什么想法吗
def to_str(key, value):
if isinstance(key, unicode):
key = str(key)
if isinstance(value, unicode):
value = str(value)
return key, value
将键和值传递给它,并向代码中添加递归以解释内部字典
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'}
假设:
- 您已经导入了collections模块,可以利用它提供的抽象基类
- 您很乐意使用默认编码进行转换(如果需要显式编码,请使用
而不是data.encode('utf-8')
)str(data)
如果您需要支持其他容器类型,那么很有希望知道如何遵循该模式并为它们添加案例。如果您希望以内联方式执行此操作,而不需要递归下降,那么这可能会起作用:
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 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())
对于非嵌套dict(因为标题中没有提到这种情况,所以其他人可能会感兴趣)
要使其全部内联(非递归),请执行以下操作:
只需使用print(*(dict.keys())
*可用于打开容器的包装,例如列表。有关*的更多信息,请检查。如果某些值是列表/集合等,您会怎么做?您忘记了tuple和frozenset,richiw为什么使用
type(data)(map(convert,data))
而不是map(convert,data)
?@AbbasovAlexander:这样您就可以返回您输入的相同类型-一个元组变成一个元组,一个列表变成一个列表,一个集合变成一个集合,依此类推。@Moberg:只有当你的数据结构嵌套了几百层的时候。是的,这似乎是正确的方法,内联版本和其他版本对于真实世界的场景来说是不够的。遗憾的是,没有可靠的内联递归方法来实现这一点。或者有基于python str(…)json约定的吗?这是我最喜欢的,只转换键,这是我一直在寻找的。小错误:在返回的dict()参数周围需要一个额外的()值。此解决方案唯一的问题是,如果您的键不是全部字符串(即int-type)@MrWonderful,这是为什么?我看不出在网络上调用str有任何问题int@Germano:当然你可以对int调用str(),但是你会得到一个str。。。。不再是整数了。因此,密钥的类型将从int更改为str,这不仅仅是将unicode更改为str——最初的问题。对于2.7及以后的版本,这可以简化为:{str(key):key的值,data.items()中的值
{str(k):str(v)表示k,v表示my_dict.items()}这有助于将我的键转换为字符串,我需要将这些字符串与我的dataframe列进行比较。虽然这段代码可能会解决这个问题,但一个好的答案应该解释代码的作用以及它的帮助方式。
{str(k): str(v) for k, v in my_dict.items()}
{str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()}
>>> d = {u"a": u"b", u"c": u"d"}
>>> d
{u'a': u'b', u'c': u'd'}
>>> import json
>>> import yaml
>>> d = {u"a": u"b", u"c": u"d"}
>>> yaml.safe_load(json.dumps(d))
{'a': 'b', 'c': 'd'}