Home > Blockchain >  Python3 Increment Dict Key If It Already Exists
Python3 Increment Dict Key If It Already Exists

Time:11-07

I am iterating through a list of dicts and want to update another dict that may have a key with the same name. Instead of overwriting the key I would like to increment the key with suffix '_[num]'. The problem is I don't know what the last incremented value is so I need to loop through all keys every time.

I can accomplish this with the below but is very inefficient with larger data sets. Is there a more efficient way to accomplish this task?

My Code:

from pprint import pprint

my_dict = {
    'key': 'A',
    'key_1': 'B',
    'key_2': 'C',
    'key_3': 'D',
    'key_4': 'E',
    'key_5': 'F',
}

my_dict_list = [
    {'key': 'G'},
    {'key': 'H'},
    {'key': 'I'},
    {'key': 'J'},
    {'key': 'K'},
]

for i in my_dict_list:
    for k, v in i.items():
        if k in my_dict:
            for num in range(2, 100):
                incremented_k = k   '_{}'.format(num   1)
                if incremented_k not in my_dict:
                    my_dict.update({incremented_k: v})
                    break

pprint(my_dict)

Desired Output:

 {'key': 'A',
 'key_1': 'B',
 'key_10': 'K',
 'key_2': 'C',
 'key_3': 'D',
 'key_4': 'E',
 'key_5': 'F',
 'key_6': 'G',
 'key_7': 'H',
 'key_8': 'I',
 'key_9': 'J'}

CodePudding user response:

If you figure out the largest number of each key in my_dict before iterating through my_dict_list, you could avoid iterating through my_dict each time.

# Max index of all the different keys, ex: {"keyA": 5, "keyB": 21, "keyC": 44}
max_index_dict = {}

# Get all the max indexes of all the keys in my_dict
for keys in my_dict.keys():
    split_key = keys.split("_")
    key = split_key[0]
    if key not in max_index_dict:
        max_index_dict[key] = 0
    else:
        val = int(split_key[1])
        last_max_index = max_index_dict[key]
        if val > last_max_index:
            max_index_dict[key] = val

# When running through my_dict_list, find and increment from the max_index_dict
for item in my_dict_list:
    for key, val in item.items():
        if key in my_dict:
            max_index_dict[key]  = 1
            incremented_k = key   '_{}'.format(max_index_dict[key])
            my_dict.update({incremented_k: val})
        else:
            my_dict.update(item)
            max_index_dict[key] = 0

CodePudding user response:

If you have only one prefix (like key_), then the next number is simply len(my_dict):

In [1]: my_dict = {
   ...:     'key': 'A',
   ...:     'key_1': 'B',
   ...:     'key_2': 'C',
   ...:     'key_3': 'D',
   ...:     'key_4': 'E',
   ...:     'key_5': 'F',
   ...: };

In [2]: len(my_dict)
Out[2]: 6

If you can have different key prefixes (like foo next to key) you can keep and update a separate dict of maximum indexes for each key prefix.

next_index = {
    "key": 6,
    "foo": 0,
}
  • Related