Home > Software engineering >  Multiple functions in a For statement
Multiple functions in a For statement

Time:04-08

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 ints which are immutable, it won't. If the they were lists or dicts 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 value 10
  • names is assigned a list, which contains a; since a is an int, names will contain 10 as well, but since it's an immutable type, changing the value of names[0] won't change the value of a; names would perhaps be better off with a name like values
  • all_funcs() is called for each name, but really each value in names
  • inside all_funcs(x), the local variable x is assigned the value passed to the function, which is 10 on the first call.
  • then, func1() is called with that value, and whatever it returns is assigned to x
  • 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 same x as the one inside all_funcs() - they have the same name, but they are difference variables in different scopes
  • the first element of x is read and assigned to a; assuming func1() returns an int 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]
  • Related