1

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!

Omer Talmi
  • 128
  • 3
  • 11
  • 3
    Don't name your file `dict.py` (if that's actually what its called); you have problems later when you try to import from this file because `dict` is the name of a built-in function. – Burhan Khalid Sep 11 '14 at 07:58
  • 1
    this should help: http://stackoverflow.com/questions/11026959/python-writing-dict-to-txt-file-and-reading-dict-from-txt-file – gwenzek Sep 11 '14 at 08:06
  • this is not really helping – Omer Talmi Sep 11 '14 at 08:12

5 Answers5

1

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

wvdz
  • 16,251
  • 4
  • 53
  • 90
1

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.

Community
  • 1
  • 1
enrico.bacis
  • 30,497
  • 10
  • 86
  • 115
1

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

Ram
  • 1,115
  • 8
  • 20
0

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.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
0

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!