# Shift a python dictionnary values

I wrote this function today that shift the values of a dictionnary:

def shift_dict(dic, shift):
# Save the dic length
dic_len = len(dic)

# Reduce the shift to the dic length
shift = shift % dic_len

# convert the dict to a tupple to reference by index
list_dic = [(k,v) for k, v in dic.iteritems()]

# Create the new shifted dict
shifted = {
list_dic[x][0]: list_dic[ (x - shift) % dic_len ][1]
for x in xrange(dic_len)
}

return shifted


The idea is to keep the keys but to assign the nth - shift value to it.

A few examples:

dic = {
'a':10,
'b':2,
'c':30,
'd':4,
'e':50,
'f':6,
}
print dic
print shift_dict(dic, 1)
print shift_dict(dic, 4)
print shift_dict(dic, -2)


Result:

{'a': 10, 'c': 30, 'b': 2, 'e': 50, 'd': 4, 'f': 6}
{'a': 6, 'c': 10, 'b': 30, 'e': 2, 'd': 50, 'f': 4}
{'a': 2, 'c': 50, 'b': 4, 'e': 6, 'd': 10, 'f': 30}
{'a': 30, 'c': 2, 'b': 50, 'e': 4, 'd': 6, 'f': 10}


I find that the "create a list and then another dictionnary" is not very effective, but I couldn't think of another way to do it.

Any thoughts?

• The result depends on the arbitrary ordering of the dict; I'm getting a different result. Seems kind of pointless to me, I'm afraid. May 14 '17 at 16:38
• First of all as @JanneKarila said if you want ordered dict you should use OrderedDict. Second this can be done much more simply. May 14 '17 at 16:59
• I noticed the ordering after this, thanks for the comment. user1685095: what do you mean, can the OrderedDict simplify this? May 14 '17 at 17:01
• Are you using 3.6, as it'd explain why the dictionary is ordered. However you shouldn't rely on this functionality. May 14 '17 at 17:15

Use OrderedDict if you want an ordered dictionary.

from collections import OrderedDict
from itertools import islice, cycle

def shift_dict(dct, shift):
shift %= len(dct)
return OrderedDict(
(k, v)
for k, v in zip(dct.keys(), islice(cycle(dct.values()), shift, None))
)

• Sorry but I've just spotted that my example was pretty bad thus, this solution does not work, I'm updating the question. May 14 '17 at 17:52
• @nobe4 Okay, I'll try to help May 14 '17 at 17:53