开发者

Reorder dictionary in python according to a list of values

开发者 https://www.devze.com 2023-03-03 21:49 出处:网络
Let us consider a dictionary: sample_dict={1:\'r099\',2:\'g444\',3:\'t555\',4:\'f444\',5:\'h666\'} I want to re-order this dictionary in an order specified by a list containing the order of the dic

Let us consider a dictionary:

sample_dict={1:'r099',2:'g444',3:'t555',4:'f444',5:'h666'}

I want to re-order this dictionary in an order specified by a list containing the order of the dictionary keys that I desire. Let us say the desired order list is:

desired_order_list=[5,2,4,3,1]

So, I want my dictionary to appear like this:

{5:'h666',2:'g444',4:'f444',3:'t555',1:'r099'}

If I can get a list of values that is fine too. Meaning, the result can be this:

['h666','g444','f444','t555','r099']

How do I achie开发者_Go百科ve this in the least complex way possible?


Answer for Python 3.6+

Guido has assured dictionaries would be ordered from Python 3.7 onwards, and they already were as an experimental feature in 3.6. The answer has already been expanded on in Fastest way to sort a python 3.7+ dictionary.

In this case, building a new dict with simple dictionary comprehension based on the items contained in the desired_order_list will do the trick.

sample_dict = {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}
print(sample_dict)
>>> {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}

desired_order_list = [5, 2, 4, 3, 1]

reordered_dict = {k: sample_dict[k] for k in desired_order_list}
print(reordered_dict)
>>> {5: 'h666', 2: 'g444', 4: 'f444', 3: 't555', 1: 'r099'}


If you're using an OrderedDict, you can do

for key in [5,2,4,3,1]:
    my_ordered_dict[key] = my_ordered_dict.pop(key)

This reinserts everything in your ordered dict in the sequence you want, such that later you can do

my_ordered_dict.values()

And get the list you suggested in the question.

If you wrap the reinsertion in a try: ...; except KeyError: pass, you can reorder an OrderedDict even if not all the keys in your list are present.


Python dictionaries are unordered.

Use OrderedDict instead.


Using an OrderedDict or Eli's solution will probably be a good way to go, but for reference here is a simple way to obtain the list of values you want:

[sample_dict[k] for k in desired_order_list]

If you aren't completely sure that every element from desired_order_list will be a key in sample_dict, use either [sample_dict.get(k) ...] or [... for k in desired_order_list if k in sample_dict]. The first method will put None in for missing keys, the second method will only include values from the keys are are in the dict.


What is the meaning of reordering the dictionary for you? Dictionaries are unordered data structures by their nature - they are used for lookup rather than order.

Do you want to iterate over the dictionary in some specific order? Then just use your desired_order_list:

for key in desired_order_list: 
  # d is the dictionary
  # do stuff with d[key]

As others have mentioned, Python has an OrderedDict (in 2.7 or 3.x), but I don't think it's what you need here. "Reordering" it is just too inefficient. It's much better to just carry your dictionary along with the list of keys in desired order, together.

If you still insist on an OrderedDict, just create a new OrderedDict, inserting the value into it in the order of desired_order_list.


The existing answers more than cover the question except in the special case when the list is incomplete and we want to keep all the values leaving all the rest in the end: Then, after creating the dictionary, update it with the old one to add the missing values:

    sample_dict = {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}
    print(reordered_dict)
    # {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}
    desired_order_list = [5, 2 ]
    reordered_dict = {k: sample_dict[k] for k in desired_order_list}
    print(reordered_dict)
    # {5: 'h666', 2: 'g444'}
    reordered_dict.update(sample_dict)
    print(reordered_dict)
    # {5: 'h666', 2: 'g444', 1: 'r099', 3: 't555', 4: 'f444'}


wouldn't be easier just doing this way?

sample_dict={1:'r099',2:'g444',3:'t555',4:'f444',5:'h666'}
new_sample_dict={
    1: sample_dict[5],
    2: sample_dict[2],
    3: sample_dict[4],
    4: sample_dict[3],
    5: sample_dict[1]
}


Use SortedDict provided by django (from django.utils.datastructures import SortedDict). SortedDict stores it's order in keyOrder attribute (which is just a list, so you can reorder it any way you like, anytime).

If you don't have django installed or have no use for django, just lift the implementation django.utils.datatstructures. It doesn't depend on any other parts of django.

0

精彩评论

暂无评论...
验证码 换一张
取 消