0

I currently have a dictionary with a numerical index as keys. I know how much values I should have in total in the dictionary and would like to add the missing keys and a null value with those keys in the dictionary. To illustrate I included this example:

dictionary = {'0' : '101',
              '1' : '102',
              '2' : '100',
              '4' : '100.5',
              '6' : '103'}

I know that I have 8 values in my dictionary and so I would like to write a function that turns the above dictionary into:

dictionary = {'0' : '101',
              '1' : '102',
              '2' : '100',
              '3' : None,
              '4' : '100.5',
              '5' : None,
              '6' : '103',
              '7' : None}

Anyone that knows how to achieve this? Thanks in advance.

4
  • 1
    How do you decide what's missing; in your example you found that '5' and '7' were missing, but what about '8', etc. You've got to refine your question to specify that the keys are always single (?) character strings that represent positive integers, and you want to find in all the gaps between those integers. Commented Aug 23, 2021 at 15:10
  • @MarkLavin, I know that the amount of values should be 8 and as it is a numerical index, the index numbers should go from 0 to 7, which is how I determine which values are missing. Commented Aug 23, 2021 at 15:14
  • You say you have a numerical keys, but your shown keys are all strings. Which is it really? Commented Aug 23, 2021 at 15:47
  • The API returned the numerical index in string format, I wrote a function to undo it. You can therefore say it was both ;) Commented Aug 24, 2021 at 17:10

7 Answers 7

2

Assuming N is the number of items

{**dictionary, **{k: None for k in range(N + 1) if str(k) not in dictionary.keys()}}

However, it might be better to have integers as keys in dictionary, in this way you do not have to cast to str

Edit Thanks to schwobaseggl comment a better version is

{**{str(k): None for k in range(N + 1)}, **dictionary}

see this question about dict merge in python

Sign up to request clarification or add additional context in comments.

4 Comments

No need for the .keys() when checking dict membership + missing one str cast. You could even be less verbose: {**{str(k): None for k in range(N+1)}, **dictionary}
@schwobaseggl Or {}.fromkeys(map(str, range(N+1))) | dictionary.
@KellyBundy Raises a TypeError for me... (Python 3.8)
@schwobaseggl Then update your Python already :-P
1

The following would do the trick:

m = max(map(int, dictionary))
for i in map(str, range(m)):
    if i not in dictionary: 
        dictionary[i] = None

But whether that is necessary is questionable as you could easily provide the default upon lookup: dictionary.get(key) will return None anyway for missing keys.

1 Comment

Or for i in range(m): dictionary.setdefault(str(i)).
0

Something like this should do the trick:

dictionary = {'0' : '101', '1' : '102', '2' : '100', '4' : '100.5', '6' : '103'}
key_list = ['0','1','2','3','4','5','6','7']
for k in key_list:
    try:
        dictionary[k]
    except KeyError:
        dictionary[k] = None

Comments

0

Otherwise, if you know that your values are following each other, you can use the following function:

def complete_dict(my_dict, begin_at=0, stops_at=8):
    for key in range(begin_at, stops_at):
        if str(key) not in my_dict.keys():
            my_dict[str(key)] = None
    return my_dict

It goes then from begin_at to stops_at - 1.

Comments

0

So, since you know that it starts with 0 and goes to some value, you can use range to loop through all the items. If it already exists, just use the same value, and if it doesn't, add None.

d = {'0' : '101', '1' : '102', '2' : '100', '4' : '100.5', '6' : '103'}

for i in range(0, 7):
    d[str(i)] = d.get(str(i), None) 

d = dict(sorted(d.items()))
print(d)

Alternatively, instead of using same dictionary and doing sort by key, you could create new dictionary, which will automatically be sorted, since you're adding them in order.

This is if you're using keys as strings (like in your example). If they are int, just lose the str(i) and use just i

Comments

0

Can't you just use if k not in dictionary: dictionary[k] = None? Or to be fancy dictionary[k] = dictionary.get(k)

You can fill the Nones if they are not present in the dictionary:

dictionary = {'0' : '101', '1' : '102', '2' : '100', '4' : '100.5', '6' : '103'}
keys = ['0','1','2','3','4','5','6','7']
for k in keys:
    if k not in dictionary:
        dictionary[k] = None

Or if you want to be fancy:

dictionary = {'0' : '101', '1' : '102', '2' : '100', '4' : '100.5', '6' : '103'}
keys = ['0','1','2','3','4','5','6','7']
for k in keys:
    dictionary[k] = dictionary.get(k)

dictionary.get(k) will return the value by key k or None if the value isn't in the dictinary.

Comments

0

The above examples work fine for filling Nones, but you should consider, maybe in the place where you're retrieving values from the dict, using dictionary.get(key, None) instead of dictionary[key]. This way you'll get None for nonexistent keys, and have your original dictionary.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.