Omer Talmi
Omer Talmi

Reputation: 126

how to Change dictionary values in python file

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!

Upvotes: 1

Views: 3785

Answers (5)

Ludwig Stumpp
Ludwig Stumpp

Reputation: 3

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!

Upvotes: 0

Ram
Ram

Reputation: 1115

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

Upvotes: 1

Padraic Cunningham
Padraic Cunningham

Reputation: 180550

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.

Upvotes: 0

enrico.bacis
enrico.bacis

Reputation: 31544

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.

Upvotes: 1

wvdz
wvdz

Reputation: 16651

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

Upvotes: 1

Related Questions