how to Change dictionary values in python file

Question:

Suppose I have a python file named ConfigFile.py that has the dictionaries:

person = {
    'name'          :       'Jhon Dow',
    'address'       :       'London',
    'age'           :       26,
    'isMarried'     :       True ,
    'brothersNames' :       ['Kim' , 'David' , 'Ron']
} 

animal = {
    'type'          :       'Lion',
    'name'          :       'Simba',
    'age'           :       10,
}

Now I want to change the person [name] to Dan.
But I want to write it to the py file.

Is there a way to it using the dictionary objects ?

Thanks!

Asked By: Omer Talmi

||

Answers:

The most legible way to do it is parse it as dict, then update it and write it to the file.

Answered By: wvdz

Well, that’s a pretty ugly design, you should use json to store data in an external file, this way it’s possible to load it and rewrite it. Consider this:

data.json

{
  "person": {
    "name": "Jhon Dow", 
    "address": "London", 
    "age": 26, 
    "isMarried": true, 
    "brothersNames": [
      "Kim", 
      "David", 
      "Ron"
    ]
  }, 
  "animal": {
    "type": "Lion", 
    "name": "Simba", 
    "age": 10
  }
}

Now let’s use this code:

import json

with open('data.json', 'r') as f:
    data = json.load(f)

data['person']['name'] = 'JSON!'

with open('data.json', 'w') as f:
    json.dump(data, f, indent=2)

Let’s take a look at the file now:

{
  "person": {
    "isMarried": true, 
    "age": 26, 
    "name": "JSON!", 
    "brothersNames": [
      "Kim", 
      "David", 
      "Ron"
    ], 
    "address": "London"
  }, 
  "animal": {
    "age": 10, 
    "type": "Lion", 
    "name": "Simba"
  }
}

Our modification is there. The order of the keys is different, if you want to preserve the order you can change the loading part like this:

from collections import OrderedDict
import json

with open('data.json', 'r') as f:
    data = json.load(f, object_pairs_hook=OrderedDict)

If you really want to use your data structure as it is now instead, use a regex (but that’s a ugly). Check here.

Answered By: enrico.bacis

You can use re to split into two lines and ast.literal_eval to change into dicts.

from ast import literal_eval
import re
with open("my_dict.py") as f:
    lines = re.split("s+n",f.read().replace(" ","")) # split and remove multiple spaces 
    person = (literal_eval(lines[0].split("=")[1])) # create person dict
    animal = (literal_eval(lines[1].split("=")[1])) # create animal dict
    person["name"] = "Dan"
    with open("my_dict.py","w") as f2: # reopen file using "w" to overwrite
        f2.write("person = {}n".format(person))
        f2.write("animal = {}".format(animal))

my_dict.py will look like:

person = {'isMarried': True, 'age': 26, 'name': 'Dan', 'brothersNames': ['Kim', 'David', 'Ron'], 'address': 'London'}
animal = {'age': 10, 'type': 'Lion', 'name': 'Simba'}

If you ever need to parse it again, it will be much easier in this format.

Answered By: Padraic Cunningham

If your file is gonna contain only dictionaries you can use the ConfigParser module to solve this , For this to happen you have to change the file format the way config parser supports

File:

[person]
name = Jhon Dow
address = London
age = 256
ismarried = True
brothersnames = Kim,David,Ron
age1 = 256

[animal]
type = Lion
name = Simba
age = 10

Code:

!/usr/bin/python
import ConfigParser
config = ConfigParser.RawConfigParser()
config.read("File")
# You can set the data by specifing the section,option and value
# Changes the age of person to 256
config.set("person","age","256") 
# Change the name of person to Dan
config.set("person","name","Dan") 
# Open the File and write to it, This will change the data
with open("File","wb") as configfile:
    config.write(configfile)

This way you can easily acess and write to file using the ConfigParser module , For detailed description of configparser module refer to : https://docs.python.org/2/library/configparser.html

Answered By: Ram

Another option is to manually scan the file line by line to find the line where we need to make the replacement:

# open file and convert into list of lines
with open("dict.py", "r") as f:
    lines = f.readlines()

# go through each line
for i, line in enumerate(lines):
    # if dictionary is found
    if "person" in line:
      # continue with lines from there onwards
      for j, line in enumerate(lines[i:])
        # if key is found
        if "name" in line:
            # replace the value of this key
            lines[i+j] = line.replace("Jhon Dow", "Dan")
            break

# save changed file
with open("dict.py", "w") as f:
    f.writelines(lines)

Of course one can adapt above script to also work when we do not know the previous value (here "Jhon Dow"). One could for example:

  • split the string by " "
  • read the last part ("’Jhon Dow’,")
  • remove the "," at the end with .rstrip()
  • remove the "’" with .strip()
  • get the leftover value ("Jhon Dow")
  • replace "Jhon Dow" in the line with the desired value using .replace()

Probably there are better ways to do this, but the idea is the same.

Hope that helps!

Answered By: Ludwig Stumpp
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.