Search code examples
pythonconfiginiconfigparser

Can I delete a specific value within a section of a config.ini file using Python configparser?


I have a config.ini file and I am trying to delete a specific value in a section of my config.ini file. I basically want to delete an index within a list. The config.ini file is:

[INPUT]
intervals = [[4000, 6000], [25000, 55000]]

For example, I want to delete [4000, 6000], so that the new config.ini file becomes:

[INPUT]
intervals = [[25000, 55000]]

My code is below with two functions, one to import the contents of config.ini (load_args()) and another to delete a section of config.ini (delete_args()). The delete function is based off an answer to How to remove a section from an ini file using Python ConfigParser?

import configparser
import ast

def load_args():
    config = configparser.ConfigParser()
    config.read('config.ini')
    interval = ast.literal_eval(config['INPUT']['intervals'])
    print(interval)

load_args()

def delete_args():
    config = configparser.ConfigParser()
    with open('config.ini', 'r+') as s:
        config.readfp(s)  
        config.remove_section('INPUT')
        s.seek(0)
        config.write(s)
        s.truncate()
        interval = ast.literal_eval(config['INPUT']['intervals'])
        print(interval)

delete_args()

The current delete_args() function above deletes everything in the config.ini. I understand that delete_args() needs a way to find the value [4000, 6000] in config.ini, so I was wondering if is possible to pass in [4000, 6000] as an argument into delete_args() that then finds the section [INPUT], and finds the specified interval ([4000, 6000]) within intervals and deletes it.


Solution

  • If I understand you correctly you want to remove a specific interval from the multi-dimensional list by argument in your delete_args function when you update the config.ini. I came up with this solution:

    import configparser 
    import ast
    
    parser = configparser.ConfigParser()
    interval = []
    
    def load_args():
        global interval
        parser.read('config.ini')
        interval = ast.literal_eval(parser['INPUT']['intervals'])
        print(interval)
    
    load_args()
    
    def delete_args(index):
        global interval
        interval.pop(index)
        parser.set('INPUT', 'intervals', str(interval))
        with open("config.ini", "w+") as configfile:
            parser.write(configfile)
    
    def delete_args2(ele):
        global interval
        interval = [x for x in interval if x != ele]
        parser.set('INPUT', 'intervals', str(interval))
        with open("config.ini", "w+") as configfile:
            parser.write(configfile)
    
    #delete_args(0)
    delete_args2([4000, 6000])
    
    delete_args(0)
    
    load_args()
    

    Output

    [[4000, 6000], [25000, 55000]]
    [[25000, 55000]]
    

    I used a bit different update strategy, and just pop() the element at the specifid index. I think this is a very clean way. If you prefer to pass in a value to remove you can use interval.remove(ele) or something more robust like [x for x in interval if x != ele] instead of the pop(index). Note: I've defined interval globally for the sake of simplicity but that's not important.