将字典的键和值从“unicode”转换为“str”的最快方法?
Posted
技术标签:
【中文标题】将字典的键和值从“unicode”转换为“str”的最快方法?【英文标题】:Fastest way to convert a dict's keys & values from `unicode` to `str`? 【发布时间】:2010-11-18 06:35:23 【问题描述】:我从一个代码“层”接收到一个字典,在将其传递到另一个“层”之前,会在该代码上执行一些计算/修改。原始字典的键和“字符串”值是unicode
,但它们被传递到的层只接受str
。
这会经常被调用,所以我想知道转换类似的最快方法是什么:
u'spam': u'eggs', u'foo': True, u'bar': u'baz': 97
...到:
'spam': 'eggs', 'foo': True, 'bar': 'baz': 97
...记住非“字符串”值需要保持其原始类型。
有什么想法吗?
【问题讨论】:
【参考方案1】:def to_str(key, value):
if isinstance(key, unicode):
key = str(key)
if isinstance(value, unicode):
value = str(value)
return key, value
将键和值传递给它,并在代码中添加递归以说明内部字典。
【讨论】:
【参考方案2】: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)
)。
如果您需要支持其他容器类型,希望很明显如何遵循该模式并为它们添加案例。
【讨论】:
如果某些值是列表/集合/等,该怎么办? 你忘记了元组和frozenset,Richi 你为什么用type(data)(map(convert, data))
而不是map(convert, data)
?
@AbbasovAlexander:这样你就可以得到你输入的相同类型——一个元组变成一个元组,一个列表变成一个列表,一个集合变成一个集合,等等。
@Moberg:只有当你的数据结构嵌套了数百层深时。【参考方案3】:
如果您想内联执行此操作并且不需要递归下降,则可能可行:
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 "
【讨论】:
对于 2.7 及更高版本,这可以简化如下: str(key):value for key,value in data.items()
【参考方案4】:
我知道我迟到了:
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())
【讨论】:
是的,这似乎是正确的做法,内联和其他版本确实不足以满足现实世界的场景。太糟糕了,没有可靠的内联无递归方式来实现这一点。或者也许有基于 python str(...) 的 json 约定? 这是我最喜欢的,只转换密钥,这是我一直在寻找的。小错字:您需要在返回的 dict() 参数周围添加一个 ()。 这个解决方案的唯一问题是如果你的键不是所有的字符串(即 int 类型) @MrWonderful 为什么会这样?我在 int 上调用str
看不出任何问题
@Germano :当然,您可以在 int 上调用 str(),但您会得到一个 str...。不再是 int。因此,键的类型将从 int 更改为 str,这比将 unicode 更改为 str 更多 - 原始问题。【参考方案5】:
对于一个非嵌套的字典(因为标题没有提到这种情况,它可能对其他人来说很有趣)
str(k): str(v) for k, v in my_dict.items()
【讨论】:
str(k): str(v) for k, v in my_dict.items() 这有助于将我的键转换为我需要与我的数据框列进行比较的字符串【参考方案6】:使其全部内联(非递归):
str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()
【讨论】:
【参考方案7】:只需使用print(*(dict.keys()))
* 可用于拆箱容器,例如列表。有关 * 的更多信息,请查看this SO answer。
【讨论】:
虽然这段代码可能会解决问题,但一个好的答案应该解释代码的什么以及它如何提供帮助。【参考方案8】:>>> 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'
【讨论】:
以上是关于将字典的键和值从“unicode”转换为“str”的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章