如何在 python3中将 OrderedDect 转换为常规 Dect

我正在努力解决以下问题: 我想像这样转换一个 OrderedDict:

OrderedDict([('method', 'constant'), ('data', '1.225')])

变成这样一个常规的结语:

{'method': 'constant', 'data':1.225}

因为我必须把它作为字符串存储在数据库中。在转换之后,订单就不再重要了,所以我还是可以保留订单特性。

谢谢你的提示和解决方案,

140334 次浏览
>>> from collections import OrderedDict
>>> OrderedDict([('method', 'constant'), ('data', '1.225')])
OrderedDict([('method', 'constant'), ('data', '1.225')])
>>> dict(OrderedDict([('method', 'constant'), ('data', '1.225')]))
{'data': '1.225', 'method': 'constant'}
>>>

然而,要将其存储在数据库中,最好将其转换为 JSON 或 Pickle 之类的格式。有了腌黄瓜,你甚至可以保持秩序!

将你的 OrderedDict转换成常规的 Dict很容易,如下所示:

dict(OrderedDict([('method', 'constant'), ('data', '1.225')]))

如果必须将其作为字符串存储在数据库中,那么可以使用 JSON。这也很简单,你甚至不必担心转换成一个常规的 dict:

import json
d = OrderedDict([('method', 'constant'), ('data', '1.225')])
dString = json.dumps(d)

或者直接将数据转储到文件中:

with open('outFile.txt','w') as o:
json.dump(d, o)

虽然这是一个一年前的问题,我想说的是,使用 dict将不会有帮助,如果你有一个有序的字典在有序的字典。最简单的方法,可以转换这些递归顺序字典将是

import json
from collections import OrderedDict
input_dict = OrderedDict([('method', 'constant'), ('recursive', OrderedDict([('m', 'c')]))])
output_dict = json.loads(json.dumps(input_dict))
print output_dict

如果您正在寻找不使用 json模块的递归版本:

def ordereddict_to_dict(value):
for k, v in value.items():
if isinstance(v, dict):
value[k] = ordereddict_to_dict(v)
return dict(value)

很简单

>>import json
>>from collection import OrderedDict


>>json.dumps(dict(OrderedDict([('method', 'constant'), ('data', '1.225')])))

下面是在 python 3.7中看起来最简单和有效的方法

from collections import OrderedDict


d = OrderedDict([('method', 'constant'), ('data', '1.225')])
d2 = dict(d)  # Now a normal dict

现在来看看这个:

>>> type(d2)
<class 'dict'>
>>> isinstance(d2, OrderedDict)
False
>>> isinstance(d2, dict)
True

注意: 这也有效,并给出相同的结果-

>>> {**d}
{'method': 'constant', 'data': '1.225'}
>>> {**d} == d2
True

还有这个

>>> dict(d)
{'method': 'constant', 'data': '1.225'}
>>> dict(d) == {**d}
True

干杯

处理嵌套字典和迭代器但不使用 json模块的版本。嵌套的字典变成了 dict,嵌套的迭代变成了 list,其他的一切都不变地返回(包括字典键和字符串/字节/字节数组)。

def recursive_to_dict(obj):
try:
if hasattr(obj, "split"):    # is string-like
return obj
elif hasattr(obj, "items"):  # is dict-like
return {k: recursive_to_dict(v) for k, v in obj.items()}
else:                        # is iterable
return [recursive_to_dict(e) for e in obj]
except TypeError:                # return everything else
return obj

您可以使用“ dict _ structor”参数。

xmltodict.parse(text, attr_prefix='',dict_constructor=dict)

如果您的数据结构可能包含内部(嵌套的) OrderedDict实例,那么您应该利用 Python 的内置 copy机制。

您可以通过 Python 的 copyreg模块(也由 pickle使用)覆盖 OrderedDict的复制行为。然后,您可以使用 Python 的内置 copy.deepcopy()函数来执行转换。

import copy
import copyreg
from collections import OrderedDict


def convert_nested_ordered_dict(x):
"""
Perform a deep copy of the given object, but convert
all internal OrderedDicts to plain dicts along the way.


Args:
x: Any pickleable object


Returns:
A copy of the input, in which all OrderedDicts contained
anywhere in the input (as iterable items or attributes, etc.)
have been converted to plain dicts.
"""
# Temporarily install a custom pickling function
# (used by deepcopy) to convert OrderedDict to dict.
orig_pickler = copyreg.dispatch_table.get(OrderedDict, None)
copyreg.pickle(
OrderedDict,
lambda d: (dict, ([*d.items()],))
)
try:
return copy.deepcopy(x)
finally:
# Restore the original OrderedDict pickling function (if any)
del copyreg.dispatch_table[OrderedDict]
if orig_pickler:
copyreg.dispatch_table[OrderedDict] = orig_pickler

仅仅通过使用 Python 内置的复制基础结构,这个解决方案就在以下方面优于本文提供的所有其他解决方案:

  • 适用于任意数据层次结构,包括嵌套的 OrderedDict

  • 不仅仅适用于 JSON 数据。

  • 不需要为每个可能的元素类型实现特殊的逻辑(例如 listtuple等)

  • deepcopy()将正确处理集合中的重复对象:

    x = [1,2,3]
    d = {'a': x, 'b': x}
    assert d['a'] is d['b']
    
    
    d2 = copy.deepcopy(d)
    assert d2['a'] is d2['b']
    

    由于我们的解决方案是基于 deepcopy(),我们将有同样的优势。

  • 这个解决方案还转换 属性,碰巧是 OrderedDict,而不仅仅是集合元素:

    class C:
    def __init__(self, a):
    self.a = a
    
    
    def __repr__(self):
    return f"C(a={self.a})"
    
    
    c = C(OrderedDict([(1, 'one'), (2, 'two')]))
    print("original: ", c)
    print("converted:", convert_nested_ordered_dict(c))
    
    original:  C(a=OrderedDict([(1, 'one'), (2, 'two')]))
    converted: C(a={1: 'one', 2: 'two'})