Converting Dict to Ordereddict

Converting dict to OrderedDict

You are creating a dictionary first, then passing that dictionary to an OrderedDict. For Python versions < 3.6 (*), by the time you do that, the ordering is no longer going to be correct. dict is inherently not ordered.

Pass in a sequence of tuples instead:

ship = [("NAME", "Albatross"),
("HP", 50),
("BLASTERS", 13),
("THRUSTERS", 18),
("PRICE", 250)]
ship = collections.OrderedDict(ship)

What you see when you print the OrderedDict is it's representation, and it is entirely correct. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)]) just shows you, in a reproducable representation, what the contents are of the OrderedDict.


(*): In the CPython 3.6 implementation, the dict type was updated to use a more memory efficient internal structure that has the happy side effect of preserving insertion order, and by extension the code shown in the question works without issues. As of Python 3.7, the Python language specification has been updated to require that all Python implementations must follow this behaviour. See this other answer of mine for details and also why you'd still may want to use an OrderedDict() for certain cases.

How to convert an OrderedDict into a regular dict in python3

>>> 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'}
>>>

However, to store it in a database it'd be much better to convert it to a format such as JSON or Pickle. With Pickle you even preserve the order!

What's wrong with passing a dict to OrderedDict?

Order is retained for keyword arguments passed to the OrderedDict

What this means is that the following is guaranteed to preserve the order:

od = OrderedDict(a=20, b=30, c=40, d=50)

that is, the order in which the keyword arguments are passed is retained in **kwargs. This, in Python 3.6, is a language feature; all other implementations need to follow suit.

How this works is, in order for this call to be performed, a dictionary is created that holds the keyword arguments. Being a dict, prior to 3.6, it lost information about the order in which these were supplied.

With PEP 468 getting accepted in 3.6, this is guaranteed to now use an ordered mapping that holds on to this information (in CPython, the "ordered mapping" happens to be a dict but, that's an implementation detail -- Update: A language feature as of Python 3.7.).


Using OrderedDict(ship), as you currently do, also preserves the order in 3.6 because dict has that implementation now, not due to PEP 468. This is something you shouldn't depend on as it is considered an implementation detail of the CPython implementation; in the future this might change (and it looks like it will) but, until then, you shouldn't depend on it.

As of Python 3.7, the previous is now guaranteed to preserve the order across implementations as dict insertion order is now a language feature.

Can I convert a defaultdict or dict to an ordereddict in Python?

Don't bother making any sort of dict at all. You don't need the properties a dict gives you, and you need the information the dict conversion loses. The record iterator from SeqIO.parse already gives you what you need:

with open(i1) as infile, open(out, 'w') as f:
for record in SeqIO.parse(infile, 'fasta'):
# Do what you were going to do with the record.

If you need the information that was in the dict key, that's record.id.

convert a dict to sorted dict in python

You cannot sort a dict because dictionary has no ordering.

Instead, use collections.OrderedDict:

>>> from collections import OrderedDict
>>> d = {'Gears of war 3': 6, 'Batman': 5, 'gears of war 3': 4, 'Rocksmith': 5, 'Madden': 3}

>>> od = OrderedDict(sorted(d.items(), key=lambda x:x[1], reverse=True))
>>> od
OrderedDict([('Gears of war 3', 6), ('Batman', 5), ('gears of war 3', 4), ('Rocksmith', 5), ('Madden', 3)])

>>> od.keys()
['Gears of war 3', 'Batman', 'gears of war 3', 'Rocksmith', 'Madden']
>>> od.values()
[6, 5, 4, 5, 3]
>>> od['Batman']
5

The "order" you see in an JSON object is not meaningful, as JSON object is unordered[RFC4267].

If you want meaningful ordering in your JSON, you need to use a list (that's sorted the way you wanted). Something like this is what you'd want:

{
"count": 24,
"top 5": [
{"Gears of war 3": 6},
{"Batman": 5},
{"Rocksmith": 5},
{"gears of war 3": 4},
{"Madden": 3}
]
}

Given the same dict d, you can generate a sorted list (which is what you want) by:

>>> l = sorted(d.items(), key=lambda x:x[1], reverse=True)
>>> l
[('Gears of war 3', 6), ('Batman', 5), ('Rocksmith', 5), ('gears of war 3', 4), ('Madden', 3)]

Now you just pass l to m['top5'] and dump it:

m["Top 5"]= l
k = json.dumps(m)

Convert Dictionary into Ordered Dictionary using Specified Order

One solution is to use an OrderedDict and a for loop.

from collections import OrderedDict

order_of_keys = ["id", "question", "choice1", "choice2", "choice3", "choice4", "solution"]

input_dict = {'id': {0: 'CB_1', 1: 'CB_2'},
'question': {0: 'Who is Ghoulsbee Scroggins?', 1: 'Who is Ebeneezer Yakbain?'},
'choice1': {0: 'Cat', 1: 'A mathematician'},
'choice2': {0: 'Dog', 1: 'A mathematician'},
'choice3': {0: 'Ape', 1: 'A mathematician'},
'choice4': {0: 'Astrophysicist', 1: 'A mathematician'},
'solution': {0: 'Ape', 1: 'A mathematician'}}

res = []

for key in input_dict['id']:
d = OrderedDict()
d['id'] = key
for k in order_of_keys[1:]:
d[k] = input_dict[k][key]
res.append(d)

Result

[OrderedDict([('id', 0),
('question', 'Who is Ghoulsbee Scroggins?'),
('choice1', 'Cat'),
('choice2', 'Dog'),
('choice3', 'Ape'),
('choice4', 'Astrophysicist'),
('solution', 'Ape')]),
OrderedDict([('id', 1),
('question', 'Who is Ebeneezer Yakbain?'),
('choice1', 'A mathematician'),
('choice2', 'A mathematician'),
('choice3', 'A mathematician'),
('choice4', 'A mathematician'),
('solution', 'A mathematician')])]

Explanation

  • Create a class which subclasses OrderedDict and defines an empty list as the default value.
  • Loop through each id. For each id, add items to an ordered dictionary aligned with the given list order_or_keys.
  • Append each OrderedDict to a result list.

converting ordered dict in python to normal dict and extract values

You are confused by Python's print representation of these dictionaries. Whether they are ordered or not is not at all the problem here, it's just that you are not printing what you say you want to print.

    for row in read:
result = rg.search(row)
print(type(result[0]))
for item in result:
print(",".join("'%s': '%s'" % (k,v) for k, v in item.items()))
# or maybe
print(",".join([item['lat'], item['lon']]))

This is similar to how print(print) just prints a representation of Python's print function, not its actual contents (which would be quite useless to a normal human reader anyway).



Related Topics



Leave a reply



Submit