简体   繁体   中英

How to change the key values of dictionary from random numbers to consecutive integers?

I have a dictionary like

dict1 = {1 : {'objects_1' : [1289,12678]} , 6 : {'objects_2' : [7798,808]} , 8 : ['object_2' : [76789,879]} }

Basically, the dict1.keys() are 1,6,8,10,15,...100 Is there a way to reassign these values with consecutive integers starting from 1,2,3,4,5..100

I would suggest recreating the dictionary using a dictionary comprehension along with enumerate .

new_dict = { index: val for index, ( _, val ) in enumerate( old_dict.items() ) }

So what you need to do is to go over the dictionary items. You can do that by iterating on keys with keys() method.

Then you could create an enumerator for each iteration. You can do that with enumerate() . enumerate() has its own value sequential starting from 0 if you do not declare anything or from a start parameter.

So for each iteration now you have the enumerate value and your key. You can assign a new key to your dictionary with the enum value as key, and as assigned value the result of the pop() method for the specific key you are each time.

Code example:

dict1 = {1 : {'objects_1' : [1289,12678]} , 6 : {'objects_2' : [7798,808]} , 8 : {'object_2' : [76789,879]} }

print(dict1)

for enum, i in enumerate(dict1.keys(), 1):
    print (enum, i)

    dict1[enum] = dict1.pop(i)

print(dict1)

EDIT based on Mad Physicist comment and thanks for reminding me

Create a New Dictionary and copy dict1.values() to it.

new_dict = {}

for key,value in enumerate(dict1.values(),1):
    new_dict[key] = value

# Output:
# new_dict = {1: {'objects_1': [1289, 12678]}, 2: {'objects_2': [7798, 808]}, 3: {'object_2': [76789, 879]}}

There is no need to use any explicit for-loops to achieve this. We can simply leverage zip and that it stops itself when one of two iterables is exhausted. We can create some arbitrarily large range as well since it is not all stored in memory either.

dict(zip(range(1, 1_000), dict1.values()))

{1: {'objects_1': [1289, 12678]},
 2: {'objects_2': [7798, 808]},
 3: {'object_2': [76789, 879]}}

Disclaimer: This will work as expected in Python 3.7+ as dict 's now preserve items in order of insertion. Otherwise we would have to use OrderedDict .

I wouldn't make any assumptions as to the insertion order of the keys, assuming you want to update the dictionary in place.

dict1 = {8 : {'objects_1' : [1289,12678]} , 6 : {'objects_2' : [7798,808]} , 1 : {'object_2' : [76789,879]} }
old_keys = list(dict1.keys())
for idx in range(1, len(old_keys) + 1):
    if idx in old_keys:
        old_keys.remove(idx)
    else:
        old_key = old_keys.pop(0)
        dict1[idx] = dict1.pop(old_key)
print(dict1)

Prints:

{1: {'object_2': [76789, 879]}, 2: {'objects_1': [1289, 12678]}, 3: {'objects_2': [7798, 808]}}

Granted this could change the insertion order of the values but will handle any arbitrary input.

If you are running Python 3.7 (or CPython 3.6) or later where the assumption is that a set maintains insertion order and its pop method will remove items in insertion order, then you could use:

dict1 = {0 : {'objects_1' : [1289,12678]} , 1 : {'objects_2' : [7798,808]} , 2 : {'object_2' : [76789,879]} }
old_keys = set(dict1.keys())
for idx in range(1, len(old_keys) + 1):
    if idx in old_keys:
        old_keys.remove(idx)
    else:
        old_key = old_keys.pop()
        dict1[idx] = dict1.pop(old_key)
print(dict1)

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