\$\begingroup\$
\$\endgroup\$
7
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?
asked May 14, 2017 at 14:57
-
2\$\begingroup\$ 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. \$\endgroup\$Janne Karila– Janne Karila2017年05月14日 16:38:03 +00:00Commented May 14, 2017 at 16:38
-
\$\begingroup\$ First of all as @JanneKarila said if you want ordered dict you should use OrderedDict. Second this can be done much more simply. \$\endgroup\$user1685095– user16850952017年05月14日 16:59:59 +00:00Commented May 14, 2017 at 16:59
-
\$\begingroup\$ I noticed the ordering after this, thanks for the comment. user1685095: what do you mean, can the OrderedDict simplify this? \$\endgroup\$nobe4– nobe42017年05月14日 17:01:40 +00:00Commented May 14, 2017 at 17:01
-
\$\begingroup\$ See my answer, please. \$\endgroup\$user1685095– user16850952017年05月14日 17:04:29 +00:00Commented May 14, 2017 at 17:04
-
\$\begingroup\$ Are you using 3.6, as it'd explain why the dictionary is ordered. However you shouldn't rely on this functionality. \$\endgroup\$Peilonrayz– Peilonrayz ♦2017年05月14日 17:15:17 +00:00Commented May 14, 2017 at 17:15
1 Answer 1
\$\begingroup\$
\$\endgroup\$
2
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))
)
Graipher
41.6k7 gold badges70 silver badges134 bronze badges
answered May 14, 2017 at 17:03
-
\$\begingroup\$ Sorry but I've just spotted that my example was pretty bad thus, this solution does not work, I'm updating the question. \$\endgroup\$nobe4– nobe42017年05月14日 17:52:19 +00:00Commented May 14, 2017 at 17:52
-
\$\begingroup\$ @nobe4 Okay, I'll try to help \$\endgroup\$user1685095– user16850952017年05月14日 17:53:13 +00:00Commented May 14, 2017 at 17:53
lang-py