Convert String to Variable Name in Python

Convert string to variable name in python

x='buffalo'    
exec("%s = %d" % (x,2))

After that you can check it by:

print buffalo

As an output you will see:
2

Convert a String to a Variable name in Python

I just cobbled a quick example to do what you want to do, I do not recommend that you do this, but I will assume that you have a good reason to and will therefore help.

vars = ["a", "b", "c"]
for i in range(len(vars)):
globals()[vars[i]] = (i+1)*10

print(a) # 10
print(b) # 20
print(c) # 30

This example may be a little complicated but it does exactly what you asked for in your question, long story short you can use the globals() function to turn a string into a variable. Link for more info here: https://www.pythonpool.com/python-string-to-variable-name/

Convert Variable Name to String?

TL;DR: Not possible. See 'conclusion' at the end.


There is an usage scenario where you might need this. I'm not implying there are not better ways or achieving the same functionality.

This would be useful in order to 'dump' an arbitrary list of dictionaries in case of error, in debug modes and other similar situations.

What would be needed, is the reverse of the eval() function:

get_indentifier_name_missing_function()

which would take an identifier name ('variable','dictionary',etc) as an argument, and return a
string containing the identifier’s name.


Consider the following current state of affairs:

random_function(argument_data)

If one is passing an identifier name ('function','variable','dictionary',etc) argument_data to a random_function() (another identifier name), one actually passes an identifier (e.g.: <argument_data object at 0xb1ce10>) to another identifier (e.g.: <function random_function at 0xafff78>):

<function random_function at 0xafff78>(<argument_data object at 0xb1ce10>)

From my understanding, only the memory address is passed to the function:

<function at 0xafff78>(<object at 0xb1ce10>)

Therefore, one would need to pass a string as an argument to random_function() in order for that function to have the argument's identifier name:

random_function('argument_data')

Inside the random_function()

def random_function(first_argument):

, one would use the already supplied string 'argument_data' to:

  1. serve as an 'identifier name' (to display, log, string split/concat, whatever)

  2. feed the eval() function in order to get a reference to the actual identifier, and therefore, a reference to the real data:

    print("Currently working on", first_argument)
    some_internal_var = eval(first_argument)
    print("here comes the data: " + str(some_internal_var))

Unfortunately, this doesn't work in all cases. It only works if the random_function() can resolve the 'argument_data' string to an actual identifier. I.e. If argument_data identifier name is available in the random_function()'s namespace.

This isn't always the case:

# main1.py
import some_module1

argument_data = 'my data'

some_module1.random_function('argument_data')


# some_module1.py
def random_function(first_argument):
print("Currently working on", first_argument)
some_internal_var = eval(first_argument)
print("here comes the data: " + str(some_internal_var))
######

Expected results would be:

Currently working on: argument_data
here comes the data: my data

Because argument_data identifier name is not available in the random_function()'s namespace, this would yield instead:

Currently working on argument_data
Traceback (most recent call last):
File "~/main1.py", line 6, in <module>
some_module1.random_function('argument_data')
File "~/some_module1.py", line 4, in random_function
some_internal_var = eval(first_argument)
File "<string>", line 1, in <module>
NameError: name 'argument_data' is not defined

Now, consider the hypotetical usage of a get_indentifier_name_missing_function() which would behave as described above.

Here's a dummy Python 3.0 code: .

# main2.py
import some_module2
some_dictionary_1 = { 'definition_1':'text_1',
'definition_2':'text_2',
'etc':'etc.' }
some_other_dictionary_2 = { 'key_3':'value_3',
'key_4':'value_4',
'etc':'etc.' }
#
# more such stuff
#
some_other_dictionary_n = { 'random_n':'random_n',
'etc':'etc.' }

for each_one_of_my_dictionaries in ( some_dictionary_1,
some_other_dictionary_2,
...,
some_other_dictionary_n ):
some_module2.some_function(each_one_of_my_dictionaries)


# some_module2.py
def some_function(a_dictionary_object):
for _key, _value in a_dictionary_object.items():
print( get_indentifier_name_missing_function(a_dictionary_object) +
" " +
str(_key) +
" = " +
str(_value) )
######

Expected results would be:

some_dictionary_1    definition_1  =  text_1
some_dictionary_1 definition_2 = text_2
some_dictionary_1 etc = etc.
some_other_dictionary_2 key_3 = value_3
some_other_dictionary_2 key_4 = value_4
some_other_dictionary_2 etc = etc.
......
......
......
some_other_dictionary_n random_n = random_n
some_other_dictionary_n etc = etc.

Unfortunately, get_indentifier_name_missing_function() would not see the 'original' identifier names (some_dictionary_,some_other_dictionary_2,some_other_dictionary_n). It would only see the a_dictionary_object identifier name.

Therefore the real result would rather be:

a_dictionary_object    definition_1  =  text_1
a_dictionary_object definition_2 = text_2
a_dictionary_object etc = etc.
a_dictionary_object key_3 = value_3
a_dictionary_object key_4 = value_4
a_dictionary_object etc = etc.
......
......
......
a_dictionary_object random_n = random_n
a_dictionary_object etc = etc.

So, the reverse of the eval() function won't be that useful in this case.


Currently, one would need to do this:

# main2.py same as above, except:

for each_one_of_my_dictionaries_names in ( 'some_dictionary_1',
'some_other_dictionary_2',
'...',
'some_other_dictionary_n' ):
some_module2.some_function( { each_one_of_my_dictionaries_names :
eval(each_one_of_my_dictionaries_names) } )


# some_module2.py
def some_function(a_dictionary_name_object_container):
for _dictionary_name, _dictionary_object in a_dictionary_name_object_container.items():
for _key, _value in _dictionary_object.items():
print( str(_dictionary_name) +
" " +
str(_key) +
" = " +
str(_value) )
######


In conclusion:

  • Python passes only memory addresses as arguments to functions.
  • Strings representing the name of an identifier, can only be referenced back to the actual identifier by the eval() function if the name identifier is available in the current namespace.
  • A hypothetical reverse of the eval() function, would not be useful in cases where the identifier name is not 'seen' directly by the calling code. E.g. inside any called function.
  • Currently one needs to pass to a function:
    1. the string representing the identifier name
    2. the actual identifier (memory address)

This can be achieved by passing both the 'string' and eval('string') to the called function at the same time. I think this is the most 'general' way of solving this egg-chicken problem across arbitrary functions, modules, namespaces, without using corner-case solutions. The only downside is the use of the eval() function which may easily lead to unsecured code. Care must be taken to not feed the eval() function with just about anything, especially unfiltered external-input data.

How to convert a string to a variable name in python

One could directly put the variables into globals:

x = ['feature1','feature2']

for varname in x:
globals()[varname] = 123

print(feature1)
# 123

This will allow creating y as specified in the question.

The fact that it's possible, however, doesn't indicate that it should be done this way. Without knowing specifics of the problem you are solving, it's difficult to advise further, but there might be a better way to achieve what you are after.

Update: in a comment @mozway raised some concerns with the above, one of which was that y will not be modified if, for example, feature2 is modified. For example:

x = ['feature1','feature2']

for varname in x:
globals()[varname] = 123

y = [feature1, feature2]
print(y)
# [123, 123]

feature2 = 456
print(y)
# [123, 123]

This seems like a useful thing to keep in mind, albeit even with regular syntax I get a similar behaviour:

feature1 = 123
feature2 = 123
y = [feature1, feature2]
print(y)
# [123, 123]

feature2 = 456
print(y)
# [123, 123]

How do I convert a string to a valid variable name in Python?

According to Python, an identifier is a letter or underscore, followed by an unlimited string of letters, numbers, and underscores:

import re

def clean(s):

# Remove invalid characters
s = re.sub('[^0-9a-zA-Z_]', '', s)

# Remove leading characters until we find a letter or underscore
s = re.sub('^[^a-zA-Z_]+', '', s)

return s

Use like this:

>>> clean(' 32v2 g #Gmw845h$W b53wi ')
'v2gGmw845hWb53wi'

Convert a string to preexisting variable names

As referenced in Stack Overflow question Inplace substitution from ConfigParser, you're looking for eval():

print eval('self.post.id') # Prints the value of self.post.id

How to use string value as a variable name in Python?

I don't understand what exactly you're trying to achieve by doing this but this can be done using eval. I don't recommend using eval though. It'd be better if you tell us what you're trying to achieve finally.

>>> candy = ['a','b','c']
>>> fruit = ['d','e','f']
>>> snack = ['g','h','i']
>>> name = 'fruit'
>>> eval(name)
['d', 'e', 'f']

EDIT

Look at the other answer by Sнаđошƒаӽ. It'll be better way to go. eval has security risk and I do not recommend its usage.

How do I turn a string into a variable name

Here's a proper solution corresponding to what you are trying to do (which is letter indexing I think) using dictionaries:

result = {}
ord = input() # why do you call that variable ord?
count = 1
for i in ord:
if i not in result:
result[i] = []
result[i].append(count)
count += 1
print(result)

No vars, no locals, no messing with an unsafe context. No problem when someone types i in your input and similar other issues. Everything safe and simple. It can be further simplified by the usage of defaultdict.

As a side note: forget about the existence of vars/locals/globals and similar objects. I've never had to use them even though I've been programming in Python for a decade. These are interesting when you write some crazy code like a Python debugger. Otherwise not needed. And these are swords that will cut you unless you're a samurai.



Related Topics



Leave a reply



Submit