Is there a possibility (e.g. a built-in function) to convert a string to a char in python? For example, if I assign a value to the variable
p1=100
and then have the string
"p1",
is it possible to assign the value of p1 to a new variable t like
t=char("p1")
so that I get
print(t)->100 ?
Obviously, above mentioned solution does not work as it throws following error message:
NameError: name 'char' is not defined
Edit: The question is not about best practices: I know that I should do this with a dictionary, but what I am trying to do is to understand data types in Python and how to convert them. Convert a string to an integer is fairly easy, for example, so I was wondering if the same applies to string to char conversions.
The eval() command does solve the example's question, but it does not answer above mentioned problem. So I would edit the goal to
char("p11")=20
which should give me
print(p11) -> 20
No. Use a dictionary.
>>> names = {'p1': 100, 'p2': 200}
>>> t = names['p1']
>>> t
100
This will throw a KeyError if the name does not exist:
>>> t = names['p3']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'p3'
... but you can use dict.get and provide a default value:
>>> t = names.get('p3', 'default')
>>> t
'default'
where the default-default-value is None.
(By the way, this has nothing to do with converting strings to a char(acter?), your terminology is quite confusing.)
You're probably looking for eval(): https://docs.python.org/3.5/library/functions.html#eval
p1 = 100
print(eval('p1')) # prints 100
If you want to evaluate expressions you can also use exec()
p1 = 100
t = 'p1 += 99'
exec(t)
print(p1) # prints 199
But as other already pointed out, you should avoid it if possible.
timgeb provided a nice alternative with dictionaries for example.
If you want to turn a string into a global variable you could also do:
globals()['y'] = 5
print(y)
Note: when you run your code in a global scope (outside a function), you can also use locals()['y'] = 5 - but this will not work in a non-global scope!
if you want to change it into character then do not use "char"
in python the char is declared as chr
so you can go like:
chr(input('Enter here'))
Related
Suppose I have
x = 3
s = "f'12{x}4'"
How to consider s as f-string to print 1234, like writing print(f'12{x}4')
when I print s, it prints it as it as: f'12{x}4'
Remve the double quotations that should fix the issue because the f in a f string needs to be outside the actuall string
You are missing two concepts.
The first one, is how you tell python your string is an f-string. The way to do this, is by adding the character 'f' before the first quotation mark:
f"this will be a f-string"
Whatever you have between {}, it will be a previously defined variable:
x = "something"
f"this will be {x}"
Assuming you ask this because you can not use actual f-strings, but also don't want to pass the parameters explicitly using format, maybe because you do not know which parameter are in the not-really-an-f-string, and also assuming you don't want to use eval, because, well, eval.
You could pass the variables in the locals or globals scope to format:
>>> x = 3
>>> s = '12{x}4'
>>> s.format(**globals())
'1234'
>>> s.format(**locals())
'1234'
Depending on where s is coming from (user input perhaps?) This might still be a bit risky, though, and it might be better to define a dict of "allowed" variables and use that in format. As with globals and locals, any unused variables do not matter.
>>> vars = {"x": x, "y": y, "z": z}
>>> s.format(**vars)
Note that this does not give you the full power of f-strings, though, which will also evaluate expressions. For instance, the above will not work for s = '12{x*x}4'.
You'd do this -
x = 3
s = f'12{x}4'
This can also work.
x = 3
s = "12{}4"
print(s.format(x))
Just remove extra commas
s = f'12{x}4'
x = 3
s = '12{}4'.format(x)
or
x = 3
print('12%s4' %x)
I am seeking to be able to use variables within the format() parentheses, in order to parameterize it within a function. Providing an example below:
sample_str = 'sample_str_{nvars}'
nvars_test = 'apple'
sample_str.format(nvars = nvars_test) #Successful Result: ''sample_str_apple''
But the following does not work -
sample_str = 'sample_str_{nvars}'
nvars_test_2 = 'nvars = apple'
sample_str.format(nvars_test_2) # KeyError: 'nvars'
Would anyone know how to do this? Thanks.
Many thanks for guidance. I did a bit more searching. For anyone who may run into the same problem, please see examples here: https://pyformat.info
sample_str = 'sample_str_{nvars}'
nvars_test_2 = {'nvars':'apple'}
sample_str.format(**nvars_test_2) #Successful Result: ''sample_str_apple''
First, I'd recommend checking out the string format examples.
Your first example works as expected. From the documentation, you are permitted to actually name the thing you are passing into {}, and then pass in a same-named variable for str.format():
'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
# returns 'Coordinates: 37.24N, -115.81W'
Your second example doesn't work because you are not passing a variable called nvars in with str.format() - you are passing in a string: 'nvars = apple'.
sample_str = 'sample_str_{nvars}'
nvars_test_2 = 'nvars = apple'
sample_str.format(nvars_test_2) # KeyError: 'nvars'
It's a little more common (I think) to not name those curly-braced parameters - easier to read at least.
print('sample_str_{}'.format("apple")) should return 'sample_str_apple'.
If you're using Python 3.6 you also have access to Python's formatted string literals.
>>> greeting = 'hello'
>>> name = 'Jane'
>>> f'{greeting} {name}'
'hello Jane'
Note that the literal expects the variables to be already present. Otherwise you get an error.
>>> f'the time is now {time}'
NameError: name 'time' is not defined
This question already has answers here:
Callable as the default argument to dict.get without it being called if the key exists
(6 answers)
Closed 6 years ago.
Seems like the fallback is called even if the key is present inside the dictionary. Is this an intended behaviour? How can workaround it?
>>> i = [1,2,3,4]
>>> c = {}
>>> c[0]= 0
>>> c.get(0, i.pop())
0
>>> c.get(0, i.pop())
0
>>> c.get(0, i.pop())
0
>>> c.get(0, i.pop())
0
>>> c.get(0, i.pop())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop from empty list
When doing c.get(0, i.pop()), the i.pop() part gets evaluated before the result it returns is passed to the c.get(...). That's the reason that the error appears if a list i is empty due to the previous .pop() calls on it.
To get around this, you should either check if the list is not empty before trying to pop an element from it, or just try it an catch a possible exception:
if not i:
# do not call do i.pop(), handle the case in some way
default_val = i.pop()
or
try:
c.get(0, i.pop())
except IndexError:
# gracefully handle the case in some way, e.g. by exiting
default_val = i.pop()
The first approach is called LBYL ("look before you leap"), while the second is referred to as EAFP ("easier to ask for forgiveness than permission"). The latter is usually preferred in Python and considered more Pythonic, because the code does not get cluttered with a lot of safeguarding checks, although the LBYL approach has its merits, too, and can be just as readable (use-case dependent).
This is the expected results because you're directly invoking i.pop() which gets called before c.get().
The default argument to dict.get does indeed get evaluated before the dictionary checks if the key is present or not. In fact, it's evaluated before the get method is even called! Your get calls are equivalent to this:
default = i.pop() # this happens unconditionally
c.get(0, default)
default = i.pop() # this one too
c.get(0, default)
#...
If you want to specify a callable that will be used only to fill in missing dictionary values, you might want to use a collections.defaultdict. It takes a callable which is used exactly that way:
c = defaultdict(i.pop) # note, no () after pop
c[0] = 0
c[0] # use regular indexing syntax, won't pop anything
Note that unlike a get call, the value returned by the callable will actually be stored in the dictionary afterwards, which might be undesirable.
There is no real way to workaround this except using if...else... !
In your case, this code would work:
c[0] if 0 in c else i.pop()
This is intended behavior because i.pop() is an expression that is evaluated before c.get(...) is. Imagine what would happen if that weren't the case. You might have something like this:
def myfunction(number):
print("Starting work")
# Do long, complicated setup
# Do long, complicated thing with number
myfunction(int('kkk'))
When would you have int('kkk') to be evaluated? Would it be as soon as myfunction() uses it (after the parameters)? It would then finally have the ValueError after the long, complicated setup. If you were to say x = int('kkk'), when would you expect the ValueError? The right side is evaluated first, and the ValueError occurs immediately. x does not get defined.
There are a couple possible workarounds:
c.get(0) or i.pop()
That will probably work in most cases, but won't work if c.get(0) might return a Falsey value that is not None. A safer way is a little longer:
try:
result = c[0]
except IndexError:
result = i.pop()
Of course, we like EAFP (Easier to Ask Forgiveness than Permission), but you could ask permission:
c[0] if 0 in c else i.pop()
(Credits to #soon)
Both the arguments are evaluated before calling the get function. Thus in all calls the size of list is decreased by 1 even if the key is present.
Try something like
if c.has_key(0):
print c[0]
else:
print i.pop()
This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 6 months ago.
I tried to assign some value to output of the eval function as below:
d = {"a": 10}
st1 = 'd'
st2 = '["a"]'
eval(st1 + st2) = 15
I got this error:
File "<stdin>", line 1
SyntaxError: can't assign to function call
I also tried this:
x = eval(st1 + st2)
x = 15
But it doesn't change the d dictionary. I tried to eval the whole assignment like this:
eval(st1 + st2 + ' = 15')
But I got this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
d["a"] = 15
^
SyntaxError: invalid syntax
I also have tried to use ast.literal_eval() function and all the results were the same. So, any idea how to do it??
EDIT 1:
For clarification as #LennartRegebro requested for, I should say that I have some dictionaries with some specific key and value pairs. I have a text file which I get from user and some of these values are defined there and I should change basic dictionaries values to these user defined ones. I have parser which parses the text file and for each change, it gives me a tuple containing dictionary name, key and value; all are strings. I wanted to do the assignments by eval function, which I understood that I can't.
EDIT 2:
As #lejlot suggested, I used globals() and added below lines to my code:
import re
pattern = re.compile(r'\["([A-Za-z0-9_\./\\-]+)"\]')
globals()[st1][pattern.findall(st2)[0]] = 15
Why don't you access your variables through globals() (or locals()) instead of eval?
d={'a':10}
globals()['d']['a']=15
print d['a']
in your particular case
d={'a':10}
s1='d'
s2='a'
globals()[s1][s2]=15
print d['a']
Do a simple,
exec(st1 + st2 + '= 15')
eval won't work. Use exec instead. That too assignment should be done inside within the argument itself.
Though using exec is a highly unrecommended practice.
Is there a way to know, during run-time, a variable's name (from the code)?
Or do variable's names forgotten during compilation (byte-code or not)?
e.g.:
>>> vari = 15
>>> print vari.~~name~~()
'vari'
Note: I'm talking about plain data-type variables (int, str, list etc.)
Variable names don't get forgotten, you can access variables (and look which variables you have) by introspection, e.g.
>>> i = 1
>>> locals()["i"]
1
However, because there are no pointers in Python, there's no way to reference a variable without actually writing its name. So if you wanted to print a variable name and its value, you could go via locals() or a similar function. ([i] becomes [1] and there's no way to retrieve the information that the 1 actually came from i.)
Variable names persist in the compiled code (that's how e.g. the dir built-in can work), but the mapping that's there goes from name to value, not vice versa. So if there are several variables all worth, for example, 23, there's no way to tell them from each other base only on the value 23 .
Here is a function I use to print the value of variables, it works for local as well as globals:
import sys
def print_var(var_name):
calling_frame = sys._getframe().f_back
var_val = calling_frame.f_locals.get(var_name, calling_frame.f_globals.get(var_name, None))
print (var_name+':', str(var_val))
So the following code:
global_var = 123
def some_func():
local_var = 456
print_var("global_var")
print_var("local_var")
print_var("some_func")
some_func()
produces:
global_var: 123
local_var: 456
some_func: <function some_func at 0x10065b488>
here a basic (maybe weird) function that shows the name of its argument...
the idea is to analyze code and search for the calls to the function (added in the init method it could help to find the instance name, although with a more complex code analysis)
def display(var):
import inspect, re
callingframe = inspect.currentframe().f_back
cntext = "".join(inspect.getframeinfo(callingframe, 5)[3]) #gets 5 lines
m = re.search("display\s+\(\s+(\w+)\s+\)", cntext, re.MULTILINE)
print m.group(1), type(var), var
please note:
getting multiple lines from the calling code helps in case the call was split as in the below example:
display(
my_var
)
but will produce unexpected result on this:
display(first_var)
display(second_var)
If you don't have control on the format of your project you can still improve the code to detect and manage different situations...
Overall I guess a static code analysis could produce a more reliable result, but I'm too lazy to check it now
This will work for simple data types (str, int, float, list etc.)
def my_print(var_str) :
print var_str+':', globals()[var_str]
You can do it, it's just not pretty.
import inspect, sys
def addVarToDict(d, variable):
lineNumber = inspect.currentframe().f_back.f_lineno
with open(sys.argv[0]) as f:
lines = f.read().split("\n")
line = lines[lineNumber-1]
varName = line.split("addVarToDict")[1].split("(")[1].split(",")[1].split(")")[0].strip()
d[varName] = variable
d = {}
a=1
print d # {}
addVarToDict(d,a)
print d # {'a': 1}
I tried the following link from the post above with no success:
Googling returned this one.
http://pythonic.pocoo.org/2009/5/30/finding-objects-names
Just yesterday I saw a blog post with working code that does just this. Here's the link:
http://pyside.blogspot.com/2009/05/finding-objects-names.html
Nice easy solution using f-string formatting, which is native to Python 3.6 and later:
vari = 15
vari_name = f"{vari=}".split("=")[0]
print(vari_name)
Produces:
vari