I have a this list
a = [OrderedDict([('a','b'), ('c','d'), ('e', OrderedDict([('a','b'), ('c','d') ]))])]
and I want to convert the OrderedDict in dictionary.
Do you know how could I do ?
Thank you !
I have a this list
a = [OrderedDict([('a','b'), ('c','d'), ('e', OrderedDict([('a','b'), ('c','d') ]))])]
and I want to convert the OrderedDict in dictionary.
Do you know how could I do ?
Thank you !
To convert a nested OrderedDict
, you could use package json
>>> import json
>>> json.loads(json.dumps(a))
[{'a': 'b', 'c': 'd', 'e': {'a': 'b', 'c': 'd'}}]
{ValueError}dictionary update sequence element #0 has length x; y is required
–
Changsha You can build a recursive function to do the conversion from OrderedDict to dict, checking for the datatypes using isinstance calls along the way.
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'}}]
However, note that OrderedDicts are dictionaries too, and support key lookups.
print(a[0]['e'])
#Output:
OrderedDict([('a', 'b'), ('c', 'd')])
a[0]['e']['c']
#Output:
'd'
So, you should not need to convert the OrderedDicts to dicts if you just need to access the values as a dictionary would allow, since OrderedDict supports the same operations.
To convert a nested OrderedDict, you could use 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}]
You should leverage Python's builtin copy
mechanism.
You can override copying behavior for OrderedDict
via Python's copyreg
module (also used by pickle
). Then you can use Python's builtin copy.deepcopy()
function to perform the conversion.
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
Merely by using Python's builtin copying infrastructure, this solution is superior to all other answers presented here, in the following ways:
Works for more than just JSON data.
Does not require you to implement special logic for each possible element type (e.g. list
, tuple
, etc.)
deepcopy()
will properly handle duplicate objects within the collection:
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'])
Since our solution is based on deepcopy()
we'll have the same advantage.
This solution also converts attributes that happen to be OrderedDict
, not only collection elements:
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'})
Demonstration on your sample data:
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'}}]
© 2022 - 2024 — McMap. All rights reserved.
dict(a)
– JudeOrderedDict
is adict
; in what sense do you need to "convert" it? – Garman