简体   繁体   中英

Python reverse dictionary items order

Assume I have a dictionary:

d = {3: 'three', 2: 'two', 1: 'one'}

I want to rearrange the order of this dictionary so that the dictionary is:

d = {1: 'one', 2: 'two', 3: 'three'}

I was thinking something like the reverse() function for lists, but that did not work. Thanks in advance for your answers!

Since Python 3.8 and above, the items view is iterable in reverse, so you can just do:

d = dict(reversed(d.items()))

On 3.7 and 3.6, they hadn't gotten around to implementing __reversed__ on dict and dict views ( issue33462: reversible dict ), so use an intermediate list or tuple , which do support reversed iteration:

d = {3: 'three', 2: 'two', 1: 'one'}
d = dict(reversed(list(d.items())))

Pre-3.6, you'd need collections.OrderedDict (both for the input and the output) to achieve the desired result. Plain dict s did not preserve any order until CPython 3.6 (as an implementation detail) and Python 3.7 (as a language guarantee).

Standard Python dictionaries (Before Python 3.6) don't have an order and don't guarantee order. This is exactly what the creation of OrderedDict is for.

If your Dictionary was an OrderedDict you could reverse it via:

import collections

mydict = collections.OrderedDict()
mydict['1'] = 'one'
mydict['2'] = 'two'
mydict['3'] = 'three'

collections.OrderedDict(reversed(list(mydict.items())))

Another straightforward solution, which is guaranteed to work for Python v3.7 and over:

d = {'A':'a', 'B':'b', 'C':'c', 'D':'d'}
dr = {k: d[k] for k in reversed(d)}

print(dr)

Output:

{'D': 'd', 'C': 'c', 'B': 'b', 'A': 'a'}

Note that reversed dictionaries are still considered equal to their unreversed originals, ie:

(d == dr) == True

In response to someone upvoting this comment, I was curious to see which solution is actually faster.

As usual, it depends. Reversing a 10,000 item dictionary 10,000 times is faster with the solution using list and reversed on the items. But reversing a 1,000,000 item dictionary 100 times (ie the same number of items in total reversed dictionaries, just a bigger starting dictionary) is faster with the comprehension - it's left up to the reader to find the exact point where it flips. If you deal with large dictionaries, you may want to benchmark either if performance matters:

from random import randint
from timeit import timeit


def f1(d):
    return dict(reversed(list(d.items())))


def f2(d):
    return {k: d[k] for k in reversed(d)}


def compare(n):
    d = {i: randint(1, 100) for i in range(n)}
    print(timeit(lambda: f1(d), number=100000000 // n))
    print(timeit(lambda: f2(d), number=100000000 // n))


compare(10000)
compare(1000000)

Results (one run, typical results):

4.1554735
4.7047593
8.750093200000002
6.7306311

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM