如何将OrderedDict转换为Dict?

5

我有一个列表

a = [OrderedDict([('a','b'), ('c','d'), ('e', OrderedDict([('a','b'), ('c','d') ]))])]

我希望将OrderedDict转换为字典。

你知道我该怎么做吗?

谢谢!


2
这不是一个有序字典,而是一个元组列表,你也可以尝试使用 dict(a) - Devesh Kumar Singh
2
你尝试过自己动手吗?也许可以调用字典构造函数? - yatu
1
你在这里写了一个列表,然后询问如何将OrderedDict转换为Dictionary?你能澄清一下你需要什么吗?此外,OrderedDict可以像字典一样正常使用,你是否有特别的原因要转换OrderedDict? - Paritosh Singh
1
这里的预期输出是什么? - Devesh Kumar Singh
8
“OrderedDict”是“dict”的一种,您需要“转换”它的意义是什么? - chepner
4个回答

11

要将嵌套的OrderedDict转换,您可以使用json包。

>>> import json
>>> json.loads(json.dumps(a))

[{'a': 'b', 'c': 'd', 'e': {'a': 'b', 'c': 'd'}}]

我尝试了你的解决方案,但是我得到了类似这样的错误:{ValueError}字典更新序列元素#0的长度为x; 需要y - Gregory Palmer

0

如果要转换一个嵌套的OrderedDict,可以使用For:

from collections import OrderedDict
a = [OrderedDict([('id', 8)]), OrderedDict([('id', 9)])]
data_list = []
for i in a:
    data_list.append(dict(i))
print(data_list)
#Output:[{'id': 8}, {'id': 9}]

0

你应该利用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内置的复制基础设施,此解决方案在以下方面优于此处提供的所有其他答案:
  • 适用于不仅仅是JSON数据。

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

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

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

    由于我们的解决方案基于deepcopy(),因此我们将具有相同的优势。

  • 此解决方案还转换了恰好是OrderedDict属性,而不仅仅是集合元素:

    class C:
        def __init__(self, a=None, b=None):
            self.a = a or OrderedDict([(1, 'one'), (2, 'two')])
            self.b = b or OrderedDict([(3, 'three'), (4, 'four')])
    
        def __repr__(self):
            return f"C(a={self.a}, b={self.b})"
    
    
    print("original: ", C())
    print("converted:", convert_nested_ordered_dict(C()))
    
    original:  C(a=OrderedDict([(1, 'one'), (2, 'two')]), b=OrderedDict([(3, 'three'), (4, 'four')]))
    converted: C(a={1: 'one', 2: 'two'}, b={3: 'three', 4: 'four'})
    

以您的样本数据进行演示:

a = [OrderedDict([('a','b'), ('c','d'), ('e', OrderedDict([('a','b'), ('c','d') ]))])]
b = convert_nested_ordered_dict(a)
print(b)

[{'a': 'b', 'c': 'd', 'e': {'a': 'b', 'c': 'd'}}]

0
你可以构建一个递归函数来将OrderedDict转换为dict,沿途使用isinstance调用检查数据类型。
from collections import OrderedDict

def OrderedDict_to_dict(arg):
    if isinstance(arg, (tuple, list)): #for some iterables. might need modifications/additions?
        return [OrderedDict_to_dict(item) for item in arg]

    if isinstance(arg, OrderedDict): #what we are interested in
        arg = dict(arg)

    if isinstance(arg, dict): #next up, iterate through the dictionary for nested conversion
        for key, value in arg.items():
            arg[key] = OrderedDict_to_dict(value)

    return arg

a = [OrderedDict([('a','b'), ('c','d'), ('e', OrderedDict([('a','b'), ('c','d') ]))])]


result = OrderedDict_to_dict(a)
print(result)
#Output:
[{'a': 'b', 'c': 'd', 'e': {'a': 'b', 'c': 'd'}}]

然而,请注意,OrderedDicts也是字典,并支持键查找。

print(a[0]['e'])
#Output:
OrderedDict([('a', 'b'), ('c', 'd')])

a[0]['e']['c']
#Output:
'd'

所以,如果你只需要像字典一样访问值,那么你不需要将OrderedDict转换为dict,因为OrderedDict支持相同的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接