Skip to content Skip to sidebar Skip to footer

How To Insert Key-value Pair Into Dictionary At A Specified Position?

How would I insert a key-value pair at a specified location in a python dictionary that was loaded from a YAML document? For example if a dictionary is: dict = {'Name': 'Zara', 'Ag

Solution 1:

On python < 3.7 (or cpython < 3.6), you cannot control the ordering of pairs in a standard dictionary.

If you plan on performing arbitrary insertions often, my suggestion would be to use a list to store keys, and a dict to store values.

mykeys = ['Name', 'Age', 'Class']
mydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'} # order doesn't matter

k, v = 'Phone', '123-456-7890'

mykeys.insert(mykeys.index('Name')+1, k)
mydict[k] = v

for k in mykeys:
    print(f'{k} => {mydict[k]}')

# Name => Zara# Phone => 123-456-7890# Age => 7# Class => First

If you plan on initialising a dictionary with ordering whose contents are not likely to change, you can use the collections.OrderedDict structure which maintains insertion order.

from collections import OrderedDict

data = [('Name', 'Zara'), ('Phone', '1234'), ('Age', 7), ('Class', 'First')] 
odict = OrderedDict(data)
odict
# OrderedDict([('Name', 'Zara'),
#              ('Phone', '1234'),
#              ('Age', 7),
#              ('Class', 'First')])

Note that OrderedDict does not support insertion at arbitrary positions (it only remembers the order in which keys are inserted into the dictionary).

Solution 2:

You will have to initialize your dict as OrderedDict. Create a new empty OrderedDict, go through all keys of the original dictionary and insert before/after when the key name matches.

from pprint import pprint
from collections import OrderedDict


definsert_key_value(a_dict, key, pos_key, value):
    new_dict = OrderedDict()
    for k, v in a_dict.items():
        if k==pos_key:
            new_dict[key] = value  # insert new key
        new_dict[k] = v
    return new_dict


mydict = OrderedDict([('Name', 'Zara'), ('Age', 7), ('Class', 'First')])
my_new_dict = insert_key_value(mydict, "Phone", "Age", "1234")
pprint(my_new_dict)

Solution 3:

This is a follow-up on nurp's answer. Has worked for me, but offered with no warranty.

# Insert dictionary item into a dictionary at specified position: definsert_item(dic, item={}, pos=None):
    """
    Insert a key, value pair into an ordered dictionary.
    Insert before the specified position.
    """from collections import OrderedDict
    d = OrderedDict()
    # abort early if not a dictionary:ifnot item ornotisinstance(item, dict):
        print('Aborting. Argument item must be a dictionary.')
        return dic
    # insert anywhere if argument pos not given: ifnot pos:
        dic.update(item)
        return dic
    for item_k, item_v in item.items():
        for k, v in dic.items():
            # insert key at stated position:if k == pos:
                d[item_k] = item_v
            d[k] = v
    return d

d = {'A':'letter A', 'C': 'letter C'}
insert_item(['A', 'C'], item={'B'})
## Aborting. Argument item must be a dictionary.

insert_item(d, item={'B': 'letter B'})
## {'A': 'letter A', 'C': 'letter C', 'B': 'letter B'}

insert_item(d, pos='C', item={'B': 'letter B'})
# OrderedDict([('A', 'letter A'), ('B', 'letter B'), ('C', 'letter C')])

Solution 4:

Would this be "pythonic"?

def add_item(d, new_pair, old_key): #insert a newPair (key, value) after old_key
    n=list(d.keys()).index(old_key)
    return {key:d.get(key,new_pair[1]) for key in list(d.keys())[:n+1] +[new_pair[0]] + list(d.keys())[n+1:] }

INPUT: new_pair=('Phone',1234) , old_key='Age'

OUTPUT: {'Name': 'Zara', 'Age': 7, 'Phone': 1234, 'Class': 'First'}

Solution 5:

Had the same issue and solved this as described below without any additional imports being required and only a few lines of code. Tested with Python 3.6.9.

  1. Get position of key 'Age' because the new key value pair should get inserted before
  2. Get dictionary as list of key value pairs
  3. Insert new key value pair at specific position
  4. Create dictionary from list of key value pairs
mydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
print(mydict)
# {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

pos = list(mydict.keys()).index('Age')
items = list(mydict.items())
items.insert(pos, ('Phone', '123-456-7890'))
mydict = dict(items)

print(mydict)
# {'Name': 'Zara', 'Phone': '123-456-7890', 'Age': 7, 'Class': 'First'}

Edit 2021-12-20: Just saw that there is an insert method available ruamel.yaml, see the example from the project page:

import sys
from ruamel.yaml import YAML

yaml_str = """\
first_name: Art
occupation: Architect  # This is an occupation comment
about: Art Vandelay is a fictional character that George invents...
"""

yaml = YAML()
data = yaml.load(yaml_str)
data.insert(1, 'last name', 'Vandelay', comment="new key")
yaml.dump(data, sys.stdout)

Post a Comment for "How To Insert Key-value Pair Into Dictionary At A Specified Position?"