将字典的键和值从“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”的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章

找到一种方法将匹配的键和值从映射推回向量

Map里面的键和值可以为空吗

将字典的键和值并行传递给函数?

枚举字典迭代键和值[重复]

Swift:字典,删除零的键和值

显示 % forloop% 的键和值的 Django 模板:如何遍历模板中的字典?