Convert a loop "for" into a function - python

I'm new to python and I want to convert a loop "for" into a function. My loop I created enables me to multiply all the number of a list and print the result. This is my loop:
a=[1,2,3,4,9]
y=1
for x in a:
y=y*x
print(y)
As you can see I tried it with a certain list and I always put y=1 to start my loop and it works very well but when I want to create a function of that loop it fails, so far I tried that:
a=[]
y=1
def produit_entier(a):
for x in a:
y=y*x
return y
a=[1,2,3,4,9]
y=1
print(produit_entier(a))
As you can see I tried it with a certain list and when I run my code it tells me "local variable 'y' referenced before assignment", and when I remove the "y=1" line and put it right after the "for x in a:" this message disappear but the result is always 1.
So I'm lost here, my function is almost exactly the same as my loop, but my loop works very well and not my function, so I would really appreciate help here. Thx in advance

The y needs to be declared inside the function, since it is used by the function.
def produit_entier(a):
y = 1
for x in a:
y=y*x
return y

Karim!
First of all, there is a problem with the return statement. You placed it the wrong way, it should be like this:
def produit_entier(a):
for x in a:
y=y*x
return y
Secondly, if you want to modify a value inside a function, which is not passed or declared inside the function - you gotta specify a global keyword to make it accessible for the modification (if you only want to read it - you do not have to specify global keyword):
def produit_entier(a):
global y
for x in a:
y=y*x
return y
Thirdly, you do not have to return a value of y though it is a global one, just print it after.
And fourthly, using global variables is actually a bad practice (since you might modify if accidentally somewhere you do not want to and it will be difficult to find). I suggest you either declare it inside the function:
def produit_entier(a):
y = 1
for x in a:
y=y*x
return y
Or just pass a value as an argument:
def produit_entier(a, y):
for x in a:
y=y*x
return y
Best of luck!

I'll provide an alternative answer using reduce:
from functools import reduce
def produit_entier(a):
return reduce(lambda x,y: x*y,a)
Or just the built-in reduce(int.__mul__, a)

Related

Can a function using a global variable use the variable's value from when the function was declared rather than when it was called?

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.

Return not functioning when applaying booleans

I'm trying something realy easy, but it's not working.
I want to change the boolean value of x, from True to False, but even though I'm returning x with it new value, when I check, it seems that the value never changed.
x = True
def example():
x = False
return x
example()
print(x)
It prints that x is True, and the boolean value of x doesnt change, I think that the problem is the use of the def and return statement, but, clearly I dont know what I'm doing wrong.
Thanks in advance! :D
Do one of the followings :
This (recommended) :
x = True
def example(x):
return not x #it will flip the value. if you need it to be always false, change it
x = example(x)
print(x)
Or This
x = True
def example():
global x
x = not x
example()
print(x)
This is thanks to the intricacies of python variable creation, and what you are trying to do is change what python sees as a global variable. This is answered in much more depth in this post but in short, adding the global keyword in functions specifying the variables will solve your problem.
x = True
def example():
global x
x = False
return x
example()
print(x)
To change the variable in the outer scope, you need to explicitly assign to it, like so:
x = True
def example():
return False
x = example()
print(x)
# False
In the code you posted, variable x in the outer scope is implicitly hidden by variable x in the inner scope of function example. When the function is done executing, the inner scope x goes out of existence, leaving just the outer scope variable x, which retains the same value as before.
SEE ALSO:
Python 2.x gotchas and landmines - Stack Overflow
Python Scope & the LEGB Rule: Resolving Names in Your Code – Real Python: Using the LEGB Rule for Python Scope

Understanding Nested functions in python

I am new in stackflow. I will so thankful if someone can help me.
I have to resolve this:
Define a nested function called nested_sum, where in the first part of the function you accept an argument called x, and in the second part (the function inside) you take another argument called y. In the function inside you have to calculate the sum of x and y.
To test your function create a variable called res_1 where you pass the x argument to nested_sum, and then create a variable called res_2 where you pass the y argument of the res_1 variable to get the final solution.
Have x equal 2 for res_1 and y equal 10 for res_2.
After looking on the internet I found a similar code, but I don't really understand how it works!
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2)
res_2 = res_1(10)
Thank you
First of all you need to realise res_1 is simply the in_sum() function.
Therefore as per your code:
nested_sum(2) puts x = 2 and then returns the in_sum() function.
res_2 = res_1(10) = in_sum(10)
Therefore x = 2 and y = 10, so thus
x + y = 2 + 10 = 12
You can write the code (easier to understand) as follows:
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2) #nested_sum return in_sum(y) location with x=2 so --> res_1= in_sum (2+y)
res_2 = res_1(10) #Cause res_1 points in_sum(2+y) res2=in_sum(2+10)=12
First of all, function in Python is an object. Think of it as a piece of paper where it is written what arguments it needs an what to do with them.
nested_sum(2) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 2 to and return it.»
nested_sum(𝑥) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 𝑥 and return it.»
Let me rename variables in your code:
def increaser_function_maker(x):
def the_new_function(y):
return x + y
return the_new_function
function_that_takes_number_and_adds_two_to_it = increaser_function_maker(2)
result = function_that_takes_number_and_adds_two_to_it(10)
There is another way to make this function. Maybe it will be easier to understand:
def increaser_function_maker(value_to_add):
return lambda i: i + value_to_add

Python recursion function issue [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 9 years ago.
I am python beginner and at the moment I am struggling with python recursion function:
x = 10
n = 3
def rec(x,n):
if n>0:
#global x2
x2 = x*n
return rec(x2,n-1)
else:
return x2
# function call:
fcall = rec(x,n)
print fcall
What confuses me is that global x2 line. With it, the function is working fine returns 60 as expected, but without it I am getting an error message:
Local variable 'x2' referenced before assignment
Why is that so?
Seems like once n reaches value of 3, and the else condition gets executed, it does not know what x2 is?
If you leave out the global, then the variable is expected to be in local scope within that function. That means that it needs to be assigned somewhere to actually exist. As the only assignment is when the n > 0 condition is true, the return x2 will always try to return a variable that does not exist.
When you add the global, you put that variable into the global scope, making it available everywhere. So it’s assigned and can be returned.
However, it’s not really a good idea to have a function depend on a global variable like that. It seems very unobvious that a global variable is required for it to work. And in fact, it’s not necessary here: Instead of x2 you want to reference x.
def rec (x, n):
if n > 0:
x = x * n
return rec(x, n - 1)
else:
return x
That way, as long as n is still bigger than zero, you multiply the current x by n and temporarily assign it to x again, which you then pass to the recursive call. If n is equal to zero, then the else case applies, and you just return the current x that was passed to the function.
Your problem is that x2 is only a local variable, so when you call the function it doesn't know the old x2 anymore.
By adding the global x2 you put that variable in the global space, so now the function can recognise it.
Check this out: http://gettingstartedwithpython.blogspot.de/2012/05/variable-scope.html
What you actually want to return is x, not x2, because you are passing the value of x2 into the next call of your recursion.
def rec(x,n):
if n>0:
x2 = x*n
return rec(x2,n-1)
else:
return x
Without global x2, assigning to x2 creates a new local variable. With it, assigning to x2 makes it change the global x2 variable. This applies only to assignment, not to looking up variables.
The current stack frame (and thus all local variables associated with it) disappears when the function returns, but globals stay forever and ever and ever (and you should also feel very bad for using them).
And also you can refactor your rec function code to:
def rec(x, n):
return rec(x*n, n-1) if n else x
A typical cause of problems for beginning programmers is the habit of using too many variables. This can make things more complicated and harder to understand. Your code can be made simpler like this:
def rec(x, n):
if n > 0:
return rec(x*n, n-1)
return x
or even this, using the ternary operator:
def rec(x, n):
return rec(x*n, n-1) if n > 0 else x
You can then try it out by just doing:
rec(3, 10)
The sooner you can build a habit creating new variables only when they are needed or improve the readability of the code, the easier your programs will be to write, debug and read.

Python functions within lists

So today in computer science I asked about using a function as a variable. For example, I can create a function, such as returnMe(i) and make an array that will be used to call it. Like h = [help,returnMe] and then I can say h1 and it would call returnMe("Bob"). Sorry I was a little excited about this. My question is is there a way of calling like h.append(def function) and define a function that only exists in the array?
EDIT:
Here Is some code that I wrote with this!
So I just finished an awesome FizzBuzz with this solution thank you so much again! Here's that code as an example:
funct = []
s = ""
def newFunct(str, num):
return (lambda x: str if(x%num==0) else "")
funct.append(newFunct("Fizz",3))
funct.append(newFunct("Buzz",5))
for x in range(1,101):
for oper in funct:
s += oper(x)
s += ":"+str(x)+"\n"
print s
You can create anonymous functions using the lambda keyword.
def func(x,keyword='bar'):
return (x,keyword)
is roughly equivalent to:
func = lambda x,keyword='bar':(x,keyword)
So, if you want to create a list with functions in it:
my_list = [lambda x:x**2,lambda x:x**3]
print my_list[0](2) #4
print my_list[1](2) #8
Not really in Python. As mgilson shows, you can do this with trivial functions, but they can only contain expressions, not statements, so are very limited (you can't assign to a variable, for example).
This is of course supported in other languages: in Javascript, for example, creating substantial anonymous functions and passing them around is a very idiomatic thing to do.
You can create the functions in the original scope, assign them to the array and then delete them from their original scope. Thus, you can indeed call them from the array but not as a local variable. I am not sure if this meets your requirements.
#! /usr/bin/python3.2
def a (x): print (x * 2)
def b (x): print (x ** 2)
l = [a, b]
del a
del b
l [0] (3) #works
l [1] (3) #works
a (3) #fails epicly
You can create a list of lambda functions to increment by every number from 0 to 9 like so:
increment = [(lambda arg: (lambda x: arg + x))(i) for i in range(10)]
increment[0](1) #returns 1
increment[9](10) #returns 19
Side Note:
I think it's also important to note that this (function pointers not lambdas) is somewhat like how python holds methods in most classes, except instead of a list, it's a dictionary with function names pointing to the functions. In many but not all cases instance.func(args) is equivalent to instance.__dict__['func'](args) or type(class).__dict__['func'](args)

Categories