How to insert key-value pair into dictionary at a specified position?
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
def insert_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
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.
- Get position of key 'Age' because the new key value pair should get inserted before
- Get dictionary as list of key value pairs
- Insert new key value pair at specific position
- 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)
Solution 4
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:
def insert_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:
if not item or not isinstance(item, dict):
print('Aborting. Argument item must be a dictionary.')
return dic
# insert anywhere if argument pos not given:
if not 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 5
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'}
Related videos on Youtube
DeepApp
Updated on July 18, 2022Comments
-
DeepApp almost 2 years
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', 'Age': 7, 'Class': 'First'}
I wish to insert the element
'Phone':'1234'
before'Age'
, and after'Name'
for example. The actual dictionary I shall be working on is quite large (parsed YAML file), so deleting and reinserting might be a bit cumbersome (I don't really know).If I am given a way of inserting into a specified position in an
OrderedDict
, that would be okay, too.-
ai2ys over 2 yearsHad the same issue with a parsed YAML file inPython 3.6.9 and solved it as described here stackoverflow.com/a/70124500/11687201
-
-
DeepApp almost 7 yearsThe problem is yaml.load loads a yaml file as a dictionary of dictionaries... (and so on). So editing has to be done on dictionaries.
-
cs95 almost 7 years@DeepApp. The solution is simple. Convert the dict to a list. Example:
dictAsList = [(k, v) for k, v in yourDict.items()]
. Now you just need to iterate over yourdictAsList
and insert your items where you like. -
Anthon almost 7 yearsIf you start with YAML, you will not necessarily preserve the key order as is available from the YAML document if you do this. It is much preferable to use the
RoundTripLoader
if you want to preserve the order, it was made (among other things) for that purpose. -
Boris Verkhovskiy over 4 yearsNot on CPython 3.6 or any other Python 3.7.
dict
s keep insertion order now, there's no need to useOrderedDict
for this -
andreis11 about 4 yearsDoes not address the question : "specified location"