Home > Back-end >  Assigning variable names from a dictionary in Python
Assigning variable names from a dictionary in Python

Time:10-15

I'm relatively new to working in Python and can't quite figure this little problem out.

I have a function that takes a .txt file input and reads each line, and based on what is on that line, it will reference a dictionary to assign a variable name. That variable is then assigned a value (also from the .txt file). I've managed to set it up to successfully do this part, but I cannot get it to return those variables as a function output.

Here is a simplified example of what I have:

The .txt file looks something like this:

File Title: 'Test_Template.env' # filename

Number of Objects: 1 # Ns

Object Size: 20 # sd

And the function is something like:

def read_env_inputs(envFilename):
    
    env_dict = {'File Title': 'filename', 
                'Number of Objects': 'Ns', 
                'Object Size': 'sd'}
    
    with open(envFilename) as f:
        lines = f.readlines()
        for line in lines:
            line = line.split(':')
            if line[0] in env_dict.keys():
                if line[0] == 'File Title':
                    vars()[env_dict[line[0]]] = line[1].split('#')[0].strip()
                else:
                    if len(line[1].split('#')[0].split(',')) == 1:
                        vars()[env_dict[line[0]]] = float(line[1].split('#')[0].strip())
                    else:
                        vars()[env_dict[line[0]]] = list(map(float,line[1].split('#')[0].split(',')))
                        
    return filename Ns sd

If I run this as a script (not a function), I end up having the properly named variables in my workspace and can manipulate them. However, this does not successfully define them in a way that allows them to be an output of the function.

I'm trying to avoid creating an if/elif statement for each variable. I'd like it to be able to reference the dictionary based on the key (which is working) and use the value associated with that key as the variable name.

CodePudding user response:

The main problem here is that you are accessing vars() which is the dictionary containing variables that are in scope and, therefore, you cannot return this. vars() something that is very rarely used and isn't the correct solution in this case.

Assuming that the txt file doesn't contain repeating lines you can do something like this:

def read_env_inputs(envFilename):

    env_dict = {"File Title": "filename", "Number of Objects": "Ns", "Object Size": "sd"}

    # Result dictionary
    res = {}

    with open(envFilename) as f:
        lines = f.readlines()
        # We already read the file and don't need to stay inside the with open block
        # Going back one level in indentation closes the file

    for line in lines:
        line = line.split(":")
        if line[0] in env_dict:  # No need for .keys()
            res_name = env_dict[line[0]]  # Name it will have in the result dictionary
            if line[0] == "File Title":
                # No need for vars()
                res[res_name] = line[1].split("#")[0].strip()
            else:
                if len(line[1].split("#")[0].split(",")) == 1:
                    # No need for vars()
                    res[res_name] = float(line[1].split("#")[0].strip())
                else:
                    # No need for vars()
                    res[res_name] = list(map(float, line[1].split("#")[0].split(",")))
    return res

You can call the function similar to this:

env = read_env_inputs(".env")
print(env["filename"])

If you really want to you can assign the result to variables like this (it shouldn't be necessary):

filename = env["filename"]
Ns = env["Ns"]
sd = env["sd"]

Or if you want to use vars() (not best practices):

for name, value in env.items():
    vars()[name] = value

Btw this code still contains some duplication. everywhere you have line[1].split("#")[0] you can substitute this for a variable (similar to what is done to res_name).

  • Related