-1

I have a dictionary as follows:

{1: 3, 2: 4, 3: 5, 4: 1, 5: 2}

I would like to rearrange it so that the value of the current pair is the key of the next pair, like this:

{1: 3, 3: 5, 5: 2, 2: 4, 4: 1}

How can I approach this?

CDJB
  • 14,043
  • 5
  • 29
  • 55
  • 2
    As far as I remember, a python dict is not specified to be ordered so there is no ordering in the key-value pairs. The order you see when printing the dictionary is arbitrary. Edit: this seems to be the case [now](https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6) :) I think you would have to create a new dictionary and insert the keys in the right order from the start as I don't think they are re-orderable. – Corentin Pane Feb 10 '20 at 13:34
  • 2
    Take a look at OrderedDict structure type: https://pymotw.com/3/collections/ordereddict.html – revliscano Feb 10 '20 at 13:35
  • 1
    Check [OrderedDict](https://docs.python.org/2/library/collections.html#collections.OrderedDict) – leoschet Feb 10 '20 at 13:35
  • 3
    Actually, as of Python 3.6, [dictionaries are ordered by insertion order](https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6) – DarrylG Feb 10 '20 at 13:37

2 Answers2

2

This is possible using the following code - dictionaries as of Python 3.7 (Python 3.6 for CPython) are ordered by insertion, so we start with the first key from d, and iterate through, updating the next key to check using the value from the last key, until the length of our new dictionary is the same as our old dictionary.

Code:

d = {1: 3, 2: 4, 3: 5, 4: 1, 5: 2}

curr = list(d.keys())[0]

d_new = {}

while len(d) > len(d_new):
    d_new[curr] = curr = d[curr]

Output:

>>> d_new
{1: 3, 3: 5, 5: 2, 2: 4, 4: 1}

Below Python 3.7, you can use an OrderedDict:

from collections import OrderedDict

d = {1: 3, 2: 4, 3: 5, 4: 1, 5: 2}

curr = 1

d_new = OrderedDict()

while len(d) > len(d_new):
    d_new[curr] = curr = d[curr]

Per the comments below, if the key/values contain a loop, we want to move to the next key-value pair. This can be achieved as follows:

Code:

d = {1: 3, 2: 4, 3: 1, 4: 1, 5: 2}

curr = list(d.keys())[0]

d_new = {}

while len(d) > len(d_new):
    if curr not in d_new:
        d_new[curr] = curr = d[curr]
    else:
        curr = next(x for x in d.keys() if x not in d_new)

Output:

>>> d_new
{1: 3, 3: 1, 2: 4, 4: 1, 5: 2}
CDJB
  • 14,043
  • 5
  • 29
  • 55
2

You could do it using accumulate from itertools:

d = {1: 3, 2: 4, 3: 5, 4: 1, 5: 2}

from itertools import accumulate
od = {k:d[k] for k in accumulate(d,lambda k,_:d[k]) }

#od : {1: 3, 3: 5, 5: 2, 2: 4, 4: 1}
Alain T.
  • 40,517
  • 4
  • 31
  • 51