Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 转换dict的最快方法&x27;s键和;从'unicode'到'str'的值?_Python_Casting_Types - Fatal编程技术网

Python 转换dict的最快方法&x27;s键和;从'unicode'到'str'的值?

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 } } …记住,非“字符串”值需要

我从一个代码“层”接收到一个dict,在将其传递到另一个“层”之前,将在该dict上执行一些计算/修改。原始dict的键和“字符串”值是
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'}