I am attempting to pass multiple objects through the same set of functions. My current approach has many nearly identical lines like this:
a=10
b=20
c=30
a = func1(a)
a = func2(a)
a = func3(a)
b = func1(b)
b = func2(b)
b = func3(b)
c = func1(c)
c = func2(c)
c = func3(c)
What I am after, and can't seem to figure out, is something like below, or something that uses map(). I believe the problem has to do with declaring dynamic variables within the function. Is there a better way to approach this?
def all_funcs(x):
x = func1(x)
x = func2(x)
x = func3(x)
return x
names = [a, b, c]
x = [all_funcs(name) for name in names]
a = x[0]
b = x[1]
c = x[2]
CodePudding user response:
Note that names
, in spite of its name, doesn't hold the names of the variables, but their actual values. Depending on the type of the variables used (whether they are mutable or not), operating on the elements of that list may or may not change the original values. In this, since they are int
s which are immutable, it won't. If the they were list
s or dict
s for example, they would.
You appear to have some misunderstandings about how this works, so it would be good to have a look at a simplified version of your code:
def all_funcs(x):
x = func1(x)
return x
a = 10
names = [a]
x = [all_funcs(name) for name in names]
a = x[0]
What happens when this program is run?
a
gets assigned the value10
names
is assigned a list, which containsa
; sincea
is anint
, names will contain10
as well, but since it's an immutable type, changing the value ofnames[0]
won't change the value ofa
;names
would perhaps be better off with a name likevalues
all_funcs()
is called for eachname
, but really each value innames
- inside
all_funcs(x)
, the local variablex
is assigned the value passed to the function, which is10
on the first call. - then,
func1()
is called with that value, and whatever it returns is assigned tox
- that value of
x
is then returned - the return value is collected in a list and once all of the calls are done, that list is assigned to
x
; note that this is not the samex
as the one insideall_funcs()
- they have the same name, but they are difference variables in different scopes - the first element of
x
is read and assigned toa
; assumingfunc1()
returns anint
as well, again that's just a copy of the value
Things would be different if a
were a list
and func1()
modified the list it was passed, it would modify the original list, before overwriting it with the new value.
Also, since you're applying func1
, func2
and func3
in order, func2
will be operating on the function result of func1
, etc. So you could just do that in one go: func3(func2(func1(some_value)))
A simpler way to achieve what you were trying to do (apply a function to a number of named values):
values = {
'a': 10,
'b': 20,
'c': 30
}
def all_funcs(d):
for key in d:
d[key] = func3(func2(func1(d[key])))
all_funcs(values)
Or, a bit more flexible:
values = {
'a': 10,
'b': 20,
'c': 30
}
def all_funcs(d, funcs):
for key in d:
for f in funcs:
d[key] = f(d[key])
all_funcs(values, [func1, func2, func3])
Since you can also put functions in a list in Python, you can just loop over the functions and apply them one after the other.
CodePudding user response:
You might consider a dictionary comprehension:
a=10
b=20
c=30
def all_funcs(x):
x = func1(x)
x = func2(x)
x = func3(x)
return x
values = [a, b, c]
results = {value: all_funcs(value) for value in values}
# Then extract the output
results[a]
results[b]
results[c]