Reputation: 67
I have a lot of data coming in dictionaries. My code runs some equations that for clarity have the same names as the dictionary keys. Lets say weight = density * volume where data['density'] is the dictionary entry.
I need a compact way to define all this variables inside the scope of my function without writing too many lines and avoiding writing data['whatever'] on every line of my equations.
I've tried this but does not work on the framework of the function.
for key in data:
exec("%s = %s" % (key, data[key]))
works fine outside the function
def weights(data):
#this is what I would like
for key in data:
key = data[key]
W1 = rho1 * V1
W2 = rho2 * V2
#where rho and V are values found in the dictionary
For more clarity, I am doing this by hand and taking many lines to do it. The name of the key is the name of the variable as you can see. I would like a compact way of unpacking the dictionary without changing the entry data to the function.
crossAreaSteel = areas["crossAreaSteel"] * mmSqTOmSq
crossAreaClad = areas["crossAreaClad"] * mmSqTOmSq
crossAreaAntiCorr = areas["crossAreaAntiCorr"] * mmSqTOmSq
crossAreaConcr = areas["crossAreaConcr"] * mmSqTOmSq
crossAreaMarineGrow = areas["crossAreaMarineGrow"] * mmSqTOmSq
crossAreaJointAntiCorr = areas["crossAreaJointAntiCorr"] * mmSqTOmSq
crossAreaJointConcrete = areas["crossAreaJointConcrete"] * mmSqTOmSq
crossAreaExternalPipe = areas["crossAreaExternalPipe"] * mmSqTOmSq
crossAreaInternalPipe = areas["crossAreaInternalPipe"] * mmSqTOmSq
rhoSteel = densities['rhoSteel']
rhoClad = densities['rhoClad']
rhoCoat = densities['rhoCoat']
Upvotes: 0
Views: 55
Reputation: 259
If you know exactly what variables are needed for the function and you can modify how the function is called, you can use the **
operator and keyword arguments to unpack the data when passing it to the function.
def function_of_rhos(rho1, rho2, V1, V2, **kwargs):
return (rho1 * V1, rho2 * V2)
my_args = {"rho1": 2, "rho2": 3, "V1": 0, "V2": 1}
my_args_with_extras = {
"rho1": 2,
"rho2": 3,
"V1": 0,
"V2": 1,
"extra1": 4,
"extra2": "yes",
}
my_args_with_missing = {"rho1": 2, "rho2": 3, "extra1": 4, "extra2": "yes"}
print(function_of_rhos(**my_args))
print(function_of_rhos(**my_args_with_extras))
print(function_of_rhos(**my_args_with_missing))
Yields
(0, 3)
(0, 3)
Traceback (most recent call last):
File "./test.py", line 19, in <module>
print(function_of_rhos(**my_args_with_missing))
TypeError: function_of_rhos() missing 2 required positional arguments: 'V1' and 'V2'
If you want to avoid the exception thrown in the last case, you could define the function to have default values that get used for things missing in the dict
def function_of_rhos(rho1, rho2, V1=3, V2=2, **kwargs):
return (rho1 * V1, rho2 * V2)
Upvotes: 1