Usng the value of a string as a variable name - python

Let's say I have a string like this.
string = "someString"
I now want to create a new instance of say, a dict() object using the variable stored in string. Can I do this?
string = dict()
Hoping it becomes "someString = dict()". Is this right? If not, how do i do it? Still learning python. Any help would be greatly appreciated.

Yes, it is possible to do this, though it is considered a bad thing to do:
string = 'someString'
globals()[string] = dict()
Instead you should do something like:
my_dynamic_vars = dict()
string = 'someString'
my_dynamic_vars.update({string: dict()})
then my_dynamic_vars[string] is a dict()

You really shouldn't do this, but if you really want to, you can use exec()
For your example, you would use this:
exec(string + " = dict()")
And this would assign a new dictionary to a variable by the name of whatever string is.

Using black magic, the kind that send you to python hell, it's possible.
The globals() and locals() functions, for example, will give you the dictionaries that contain variables currently in scope as (key, value) entries. While you can try to edit these dictionaries, the results are sometimes unpredictable, sometimes incorrect, and always undesirable.
So no. There is no way of creating a variable with a non-explicit name.

If the variable you want to set is inside an object, you can use setattr(instance,'variable_name',value)

Related

Flip variable and it's value

I've done some looking on how I can flip a variable name and that variable's value, but I have come up empty-handed.
What I want
Let me clarify what I would like with an example.
Imagine I had a variable called my_variable and it's value would be a string 'my_new_variable'
my_variable = 'my_new_variable'
Is there any way that I can flip these so that it may look like this
my_new_variable = 'my_variable'
A dict is the appropriate way to do this. Driving internal symbol names with data is a strong sign of poor program design. Please use the dict, and refer to XY Problem. External data should drive data relations, but not the internal representation. By doing so, you make your algorithm's structure dependent on the data. Data manipulation should be independent of those specific values.
You can do it;; a little research on this site will give you the references. Don't.
Should you want to do that, how about
globals()[my_variable] = 'my_variable'
You can try doing this (after installing python-varname):
from varname import nameof
my_variable = 'my_new_variable'
exec("%s = '%s'" % (my_variable, nameof(my_variable))
One way this could be done and suggested by almost everyone who has commented is by using a dictionary then flipping the keys and values.
variables = {'my_variable':'my_new_variable'}
flipped = {v:k for k,v in variables.items()}
output
{'my_new_variable': 'my_variable'}

Python: Create a variable using something other than a plain string? [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 2 years ago.
In a different question I tried to use an enumerate and for element to create a pandas dataframe using the element as the name. It turns out the problem is more general. Is there anyway to set a variable value using something other than a plain string? In Bash this is done with the Read command, which takes the previous output into a subshell and assigns it to a variable name (I'll post my question on that below).
Any way to do this in Python? i.e., something simple like:
list1[0] = pd.dataframe(data), where list1[0] is a string. Or similarly using a dict key where the value is a dataframe:
for i in dict1: i = dict1[key] or for i in dict1: function(i) = dict1[key]?
The latter doesn't work using str() or any function because the error complains "SyntaxError: can't assign to function call", but maybe something similar?
Python: How can I use an enumerate element as a string?
https://unix.stackexchange.com/questions/338000/bash-assign-output-of-pipe-to-a-variable
https://unix.stackexchange.com/questions/574920/bash-how-to-get-stdout-to-console-and-also-pipe-to-next-command
EDIT:
Okay, well, after extended discussion with #juanpa.arrivillaga, he explained that strings are not plain strings as in Bash. Let's see if I have this right.. they are string objects stored in dict objects. (even integers are stored as objects unless using numpy or pandas which expand on Python arrays). Inside a for i in dict1: loop print(i) works because 'print will call str implicitly on any object you pass to it'. i = value does not because 'think of variables as nametags you throw on objects' and i is being resolved in its for loop scope as a dict object key. I'm not sure why, but variable 'nametags' cannot be string objects.
A workaround using globals() kind of mentioned in the Duplicate answers exists:
for key in dict1: globals()[key] = pd.DataFrame()
This is because in CPython, they used actual python objects to implement the global namespaces. It might be possible to 'maybe use ctypes to modify the namespace array in a local scope', as another workaround is to use SimpleNamespace to create a new object to store variables (presumably because they are stored as objects, the same as in globals(). And to wrap up, 'setattr(sys.modules[_name_], var_name, var_value) is equivalent to globals()[var_name] = var_value'.
Sorry it's quite hard to understand what exactly the question is.
for i in dict1: function(i) = dict[key]
A couple of problems with this: the thing on the left is what you're assigning, so the syntax should be dict[key] = function(i) (but don't call your dicts 'dict' because that's a reserved keyword). This is assuming key is defined somewhere. This is why you're getting the error you describe - you cant assign to a function call, you assign to variables.
As for storing things in list, you can put whatever you like in there, same with dictionaries. For example:
import pandas as pd
ls = [pd.DataFrame(), 'Hello']
d = {
'a': pd.DataFrame(),
1: pd.DataFrame()
}
print(ls)
print(d['a'])
print(d[1])
I think this issue can be solved with dictionaries:
var_names = ['your_string', 'your_second_string']
dict = {}
for i, var_name in enumerate(var_names):
var_name = f'var_name{i}'
dict[var_name] = pd.DateFrame([])

Assigning a variable to part of a value

So I am writing a program in python3 and Im stuck on one part. My problem is I have a variable. example:
variable = 12345
so I want to assign a specific variable to one part of the value of the other variable.
Ive tried example:
variable[2] = 55
(this is an example but hopefully im coming off clear enough)
so I want to take the 3rd digit in "12345" 12[3]45
so the "3" I want to assign a variable basically from a place inside another variable.
What sucks is it has to be inside that variable. Ive thought about passing it as a string instead but I think that will change the whole rest of the script being that now its a string.
so I thought also about each time I need to call that variable I can pass it as a string to another variable but im trying not to get swamped with a million str and int swaps. I hope Ive made this understandable...I get that its not very clear lol but Ive confused my self with this script any help will be much appreciated :)
In any case we have to perform conversions to strings and lists. We can achieve this in compatible way with python2.x and python3.x as follow:
# input variable
variable = 12345
# convert that variable to list
variable_lst = [int(i) for i in str(variable)]
# change necessary digit by list index
variable_lst[2] = 55
# reverse conversion then assign updated data to variable
variable = int(''.join(str(j) for j in variable_lst)) # 125545
you should convert your variable to list type, so you could change any index of it:
var = 12345
var_list= list(str(var))
var_list[2]=55
var_list= int(''.join(str(i) for i in var_list))

global variables and .format()

I wrote a python script that generates PDF reports. I had to do some data manipulation to change column names in each of the data sets I used.
My question is, Is there a way to set a global variable and then using .format() inside the Target_Hours_All.rename() ???
I have hardcoded each column name.
For example, Target_Hours_All.rename(columns = {'VP_x':'VP', '2018 Q1 Target Hours':'hourTarget18Q1'}, inplace = True)
However, I want to be able to run this each quarter without having to update every df.rename. Instead, I would like to have global variables at the top of the script and change those.
Any help would be greatly appreciated!!!
Easiest way? Move the strings you want to change out of the function call into variables and then use the variables within Target_Hours_All.rename()
This makes the code way lot easier to read.
I can only guess what Target_Hours_All.rename does. But my guess would be that it takes the hash in "columns" and replaces the key with the value. Correct?
So could write your columns line as:
columns = {}
vpl = 'VP_x'
vpr = 'VP'
columns[vpl] = vpr
target_hours_l = '20{year} {quarter} Target Hours'.format(year='18', quarter='Q1')
target_hours_r = 'hourTarget{year}{quarter}'.format(year='18',quarter='Q1')
columns[target_hours_l] = target_hours_r
Target_Hours_All.rename(columns = columns, ... )
Yes this is more code and I should not have named my has columns but something else instead. So there is way for improvement. But it shows how you can use .format() for your call.

Enigmatic Naming of Lists in Python

I am writing a program in python and I am using a dictionary. I need to create an empty list for each key in the dictionary, and each list needs to have the same name as the key. The keys are user entered, which is why I can't just make a list in the conventional way.
This was the first thing I tried
a = {"x":1, "y":2, "z"3}
list(a.keys())
a.pop() = [] # This raises an error
I also tried to make the lists when the dictionary was being created, but this did not work either:
a = {}
b = input("INPUT1")
c = input("INPUT2")
a[b] = c
b = []
This created a list with the name "b" rather than whatever the user entered. Please help!!
This really doesn't make much sense. Why do your lists need 'names'? For that matter, what do you mean by 'names'?
Secondly, your code doesn't do anything. a.keys() is already a list. Calling list on it doesn't do anything else. But in any case, whatever the result of that line is, it is immediately thrown away, as you don't store the result anywhere.
pop doesn't work on dictionaries, it works on lists. And what does it mean to set the result of pop to a list? Are you trying to dynamically create a set of local variables with the names of each key in the dictionary? If so, why? Why not simply create another dictionary with the keys of the first, and each value as a new list? That can be done in one command:
b = dict((k, []) for k in b.keys())
(Note that dict.fromkeys() won't work here, as that would cause each element to share the same list.)
Use raw_input instead. input expects a valid Python expression and WILL evaluate whatever the user inputs. So if the user inputs a word, it'll evaluate that word and try to find an object with its name.
EDIT: for further clarification, input("INPUT1") is the equivalent of doing eval(raw_input("INPUT1")), for instance.

Categories