In my code, I have a dictionary of values along with a key called 'custom'
which allows me to input an arbitrary value. When I print key values that are NOT 'custom'
it still hits the input()
field:
Ip = {'argon':15.76,
'neon':21.56,
'krypton':14.00,
'xenon':12.13,
'helium':24.59,
'hydrogen':15.42,
'custom': float(input('Enter ionization potential (eV): '))}
print(Ip['argon'], Ip['helium'])
output:
Enter ionization potential (eV): 1
15.76 24.59
I was under the impression that keys and their associated values are kept suppressed until called, but clearly I misunderstand how dictionaries work.
A quick and dirty way of ameliorating this was to make a conditional statement, but there could be (for some reason) multiple input()
dictionary definitions such that I'd have to hard-code a conditional statement for each one. Is there a more Pythonic way of doing this?
def func(key):
if key == 'custom':
Ip = {key:float(input('Enter ionization potential (eV): '))}
# Is there a way to remove the need for a conditional statement?
else:
Ip = {'argon':15.76,
'neon':21.56,
'krypton':14.00,
'xenon':12.13,
'helium':24.59,
'hydrogen':15.42}
return print(Ip[key])
func('argon')
output:
15.76
CodePudding user response:
It is being called, as you've realized. When you define the dict, the call is evaluated and its result is inserted into the dict under 'custom'
, so in that example, 'custom': 1.0
. To avoid the call, make it a function instead.
Now that raises the question of how to have mixed types in a dict (floats and functions) and special-casing the functions. One way to get around that is to have two separate dicts: one with floats and a fallback one with functions. For example:
def func(key):
ionization_potential = {
'argon': 15.76,
'neon': 21.56,
'krypton': 14.00,
'xenon': 12.13,
'helium': 24.59,
'hydrogen': 15.42}
functions = {
'custom': lambda: float(input('Enter ionization potential (eV): '))}
try:
v = ionization_potential[key]
except KeyError:
f = functions[key]
v = f()
return v
Demo:
>>> func('argon')
15.76
>>> func('custom')
Enter ionization potential (eV): 1
1.0
Lastly, if a key is not found in either dict, this will raise a KeyError
from KeyError
, so if I were you, I'd raise a ValueError from None
in that case, since the problem is with the value of the argument:
try:
f = functions[key]
except KeyError:
raise ValueError(f'key not found: {key!r}') from None
v = f()
Demo:
>>> func('foobar')
Traceback (most recent call last):
...
ValueError: key not found: 'foobar'