working on some code has a func. that goes through if statements I want to assign this to a vaiable that i can use to redefine a list.
everything! cries in python
Code here
Expected : Works
Actual: don't Works
Because of the fact that functions are a type of object (a callable object) a variable can be assigned an instance of that object.
def bar():
return 'foo'
x = bar
print(x) #O <function at #number>
print(x()) #Output: 'foo'
Yeah you can define a function and assign that function to a variable. Then you can call that variable by providing args like any other function.
For example.
>>> def example_function(x, y):
... return x + y
...
>>> func_var = example_function
>>> func_var(10, 20)
30
Will work. It doesn't really accomplish anything though.
If you provide an example of what you want to accomplish I can give a better example.
Related
def myfunc(n):
return lambda a : a * n
mytripler = myfunc(3)
print(mytripler(11))
I am trying to learn about the lambda function in python. I understand the other examples given inside w3schools about the Lambda function. This example, however, I could not wrap my head around. How is it that mytripler(11) multiplies 3 by 11?
Note that there is nothing particularly special about lambda. It's just a convenient method of creating an anonymous function.
If the code had instead been written:
def myfunc(n):
def inner(a):
return a * n
return inner
It would be the exact same thing. Except now we've given anonymous function a name inner. But you'd discover that you can still write mytripler = myfunc(3) and it works the same way.
Python understands closures. If a variable is used (but not modified) inside an inner function, and there is an identically named variable defined in a containing function, then Python realizes that the inner variable refers to whatever value that outer variable has.
Let's take a step back: What is a function?
One definition could be that's a construct where you give it arguments, it does something and it returns a value (Let's ignore for now the cases where you don't give any arguments or where you don't receive any return value)
In Python, since everything is an object, this kind of construct is a value that can be assigned a name. For example:
>>> def example_function(argument):
... result = argument * 42
... return result
...
>>> other_name_for_example_function = example_function
>>> example_function(3)
126
>>> other_name_for_example_function(3)
126
>>> example_function == other_name_for_example_function
True
>>> example_function is other_name_for_example_function
True
Note that in the comparison made at the end, I do not call these functions, I just compare the value of example_function and other_name_for_example_function which in this case is the same "function mechanism".
Now, lambdas are another way to define a function but it's more restricted and the function isn't assigned a name automatically. Let's take the same example but with lambdas:
>>> example_lambda = lambda argument: argument * 42
>>> other_name_for_example_lambda = example_lambda
>>> example_lambda(3)
126
>>> other_name_for_example_lambda(3)
126
>>> example_lambda == other_name_for_example_lambda
True
>>> example_lambda is other_name_for_example_lambda
True
Now if we replace the function call of your example with its content, it would look like this:
>>> n = 3 # just you see where that value will be used
>>> mytripler = lambda a: a * n
>>> a = 11 # also to see where that value will be used
>>> mytripler(a)
33
So, in your example,
myfunc() provide a "function mechanism" as a return value. In the definition of that "function mechanism", you have inserted the value 3 which is an argument of myfunc()
You assign the name mytripler to that function returned
You call it like you would with any function
Does that help you understand?
Here is a very simplified example of what I am trying to do:
x = 3
def f():
print(x)
x = 5
f() #f prints 5 but I want it to print 3.
Is there a way, when declaring the function, to turn x into a constant that points somewhere other than the global variable x? I can't provide arguments to the function.
This is a pretty common trick (you usually see it in lambda expressions that want to bind a particular value within a loop):
x = 3
def f(x=x):
print(x)
x = 5
f() # prints 3
The trick is that default parameter values are evaluated at the time of function definition, so in the expression x=x, the x on the right hand side is evaluated (producing the value 3) and then stored as the default value of the x parameter in the function (which shadows the x in the outer scope).
You could equivalently write:
x = 3
def f(n=x):
print(n)
x = 5
f() # prints 3
which has the same result, but doesn't shadow the x variable.
From what I understand, you seem to want x to hold two values simultaneously - which is what complex data structures are for. A list would work fine, or a dict:
>>> x = [3]
>>> def f():
... print(x[0]) # always refers to first element. Functionally constant.
...
>>> x.append(5)
>>> f()
3
>>>
However, it sounds like you really have an XY problem, where you're asking about your solution instead of your actual problem. Go back to your code and check if this seems to be the case. If so, we might be able to point you towards a better way of solving your real issue.
a function (funcA) that takes a function (funcB) and returns a function that can be evaluated to produce the same value that funcB would produce (if given the same arguments) plus 1
returned_func(x) = funcB(x) + 1
What could be the possible way of doing this? I am confused with the second part of the question as to how can a function return a value and function at the same time. Any code example would be much appreciated! Thanks!
The concept you're looking for is, essentially, a function decorator. In Python, functions are first-class objects, just like class instances are in other languages. That means that you can pass them around, just like any other object. For example:
def foo(x):
return x + 1
print(foo) # <function foo at 0x0000024202F43EA0>
bar = foo
print(bar) # <function foo at 0x0000024202F43EA0>
Here we created a reference to the function object itself. We can, using the same idea, make a function which returns a function:
def foo(x):
def inner(y):
return x + y
return inner
func = foo(5)
print(func(3)) # 8
func is assigned to the return value of foo, which is itself a function that we can evaluate. You want to return a function A that adds 1 to the result of another function, B. So, pass B to a function make_A:
def make_A(b):
def inner(x):
return b(x) + 1
return inner
def B(x):
return x
A = make_A(B)
print(A(1)) # 2
Python has excellent syntactic sugar for this type of function. See this primer for more information.
def func1(x):
#operations go here:
return(x + 1)
def func2():
#operations go here:
return(x - 1)
if func1(2) == func2(4):
print("Hooray")
Does this help? It is a demonstration of how parameters and return values can interact.
A segment like func(1) implies the return value with the parameter as 1.
In this case, I want that the program print "X = changed"
class Clase:
def __init__(self,variable):
self.var = variable
def set_var(self):
self.var = 'changed'
X = 'unchanged'
V = Clase(X)
V.set_var()
print "X = ",X
All values are objects and are passed by reference in Python, and assignment changes the reference.
def myfunc(y):
y = 13
x = 42 # x now points at the integer object, 42
myfunc(y) # inside myfunc, y initially points to 42,
# but myfunc changes its y to point to a
# different object, 13
print(x) # prints 42, since changing y inside myfunc
# does not change any other variable
It's important to note here that there are no "simple types" as there are in other languages. In Python, integers are objects. Floats are objects. Bools are objects. And assignment is always changing a pointer to refer to a different object, whatever the type of that object.
Thus, it's not possible to "assign through" a reference and change someone else's variable. You can, however, simulate this by passing a mutable container (e.g. a list or a dictionary) and changing the contents of the container, as others have shown.
This kind of mutation of arguments through pointers is common in C/C++ and is generally used to work around the fact that a function can only have a single return value. Python will happily create tuples for you in the return statement and unpack them to multiple variables on the other side, making it easy to return multiple values, so this isn't an issue. Just return all the values you want to return. Here is a trivial example:
def myfunc(x, y, z):
return x * 2, y + 5, z - 3
On the other side:
a, b, c = myFunc(4, 5, 6)
In practice, then, there is rarely any reason to need to do what you're trying to do in Python.
In python list and dict types are global and are passed around by reference. So if you change the type of your variable X to one of those you will get the desired results.
[EDIT: Added use case that op needed]
class Clase:
def __init__(self,variable):
self.var = variable
def set_var(self):
self.var.test = 'changed'
class ComplicatedClass():
def __init__(self, test):
self.test = test
X = ComplicatedClass('unchanged')
print('Before:', X.test)
V = Clase(X)
V.set_var()
print("After:",X.test)
>>> Before: unchanged
>>> After: changed
strings are immutable so you could not change X in this way
... an alternative might be reassigning X in the global space... this obviously will fail in many many senarios (ie it is not a global)
class Clase:
def __init__(self,variable):
self.var = variable
def set_var(self):
globals()[self.var] = 'changed'
X = 'unchanged'
V = Clase('X')
V.set_var()
print "X = ",X
the other alternative is to use a mutable data type as suggested by Ashwin
or the best option is that this is probably not a good idea and you should likely not do it...
Let's say I have a function
def x():
print(20)
Now I want to assign the function to a variable called y, so that if I use the y it calls the function x again. if i simply do the assignment y = x(), it returns None.
You simply don't call the function.
>>> def x():
>>> print(20)
>>> y = x
>>> y()
20
The brackets tell Python that you are calling the function, so when you put them there, it calls the function and assigns y the value returned by x (which in this case is None).
When you assign a function to a variable you don't use the () but simply the name of the function.
In your case given def x(): ..., and variable silly_var you would do something like this:
silly_var = x
and then you can call the function either with
x()
or
silly_var()
when you perform y=x() you are actually assigning y to the result of calling the function object x and the function has a return value of None. Function calls in python are performed using (). To assign x to y so you can call y just like you would x you assign the function object x to y like y=x and call the function using y()
The syntax
def x():
print(20)
is basically the same as x = lambda: print(20) (there are some differences under the hood, but for most pratical purposes, the results the same).
The syntax
def y(t):
return t**2
is basically the same as y= lambda t: t**2. When you define a function, you're creating a variable that has the function as its value. In the first example, you're setting x to be the function lambda: print(20). So x now refers to that function. x() is not the function, it's the call of the function. In python, functions are simply a type of variable, and can generally be used like any other variable. For example:
def power_function(power):
return lambda x : x**power
power_function(3)(2)
This returns 8. power_function is a function that returns a function as output. When it's called on 3, it returns a function that cubes the input, so when that function is called on the input 2, it returns 8. You could do cube = power_function(3), and now cube(2) would return 8.
lambda should be useful for this case.
For example,
create function y=x+1
y=lambda x:x+1
call the function
y(1)
then return 2.
I don't know what is the value/usefulness of renaming a function and call it with the new name. But using a string as function name, e.g. obtained from the command line, has some value/usefulness:
import sys
fun = eval(sys.argv[1])
fun()
In the present case, fun = x.
def x():
print(20)
return 10
y = x
y()
print(y)
gives the output
20
<function x at 0x7fc548cd3040>
so it does not actually assign the value returned by x() to the variable y.