Need help for Python3 - python

def a(inp):
i = 0
x = 0
for i in range(len(inp)):
b(x)
print(x)
def b(x1):
x1 = x1 + 1
def c ():
a1 = a("...")
c()
This code gives the output:
0
0
0
I don't understand why x value doesn't change?

Python has a concept of mutable and non mutable things. Mutable things include things like list, dict etc. But an integer is non-mutable, so when you change it you have to reassign it back.
for e.g.
def b(l):
l += [1]
a= [1,2,3]
b(a)
print(a)
def c(l):
l += 1
a= 1
c(a)
print(a)
This code with output
[1, 2, 3, 1]
1
Since int is non mutable and list is mutable. For more you can check https://www.geeksforgeeks.org/mutable-vs-immutable-objects-in-python/.

x1 = x1 + 1 can't change x. x is passed as a value* to b. Reassigning x1 will only change what value x1 is looking at. Returning the value from the function and reassigning it at the call site would be the simplest way to achieve what you want:
. . .
for i in range (len(inp)):
x = b(x)
print(x)
def b(x1):
return x1 + 1
* It's a little more complicated than that, but that's the simplest way to think about it for now while dealing with numbers.

x1 = x1 + 1 in your function b(x1) doesn't change the value of the variable passed into b(). So outside the function, x remains unchanged at 0.

It's just changing the x1 variable in that function's scope. To assign it to x, return the new value:
def b(x1):
return x1 = x1 + 1
Then set the return value to x:
for i in range (len(inp)):
x = b(x)
print(x)
It is also recommended to do get the value of i, as it is the position.

Related

Why are lists created by a function not iterable

I'm new to python and don't understand much. I created a function that takes a number and puts all the integers which lead up to that number, including that number, into a list. Or so I thought, turns out I cant actually use the created list as a list. Any ideas on how I can make it useable?
def break_up(x):
"""breaks up the the integers adding up to a number x, starting at 1. Works for any positive number or 0"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
print(a)
As people have commented, your indentation is incorrect, but in addition you are not actually calling the function.
The function needs to return an object. An object created in a function stays there and is not visible outside (unless it is global) - this is called encapsulation and is an important programming technique which enables functions to be used anywhere.
Note that even the multi-line comment has to be indented (and I have made it multi-line)
Here is my version of your program:
def break_up(x):
"""
breaks up the the integers adding up to a number x, starting at 1.
Works for any positive number or 0
"""
y = 1
b = 1
a = []
while y <= x:
n = x - x + b
b = b + 1
y = y + 1
a.append(n)
return a # <<<< added
# At this point, the name 'a' is not visible
thing = break_up(5)
print(thing)
# or
print(break_up(5))
Just for fun, try this:
$ python3 -i gash.py
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
>>> help(break_up)

python - enter the correct number of variables based on function handle

I have a list of variables, and a function object and I would like to assign the correct number of variable depending on the function.
def sum2(x,y):
return x + y
def sum3(x,y,z):
return x + y + z
varList = [1,2,3]
so if f = sum2 , I would like it to call first 2 elements of varList, and if f = sum3 , to call it with 3 elements of the function.
This can be done in a single function, if you are always returning the sum of all the passed arguments.
def sum1(*args):
return sum(args)
This is just utilizing positional arguments, as you don't appear to need to explicitly set individual values. It is also most flexible than the solution provided by ZdaR, as you don't need to know ahead of time the maximum number of arguments you can receive.
Some examples:
>>> print sum1(1, 2, 3)
6
>>> print sum1(1)
1
>>> print sum1(-1, 0, 6, 10)
15
Use the inspect module as follows:
import inspect
n2 = len(inspect.getargspec(sum2)[0])
n3 = len(inspect.getargspec(sum3)[0])
sum2(*varList[0:n2])
sum3(*varList[0:n3])
getargspec returns a 4-tuple of (args, varargs, keywords, defaults). So the above code works if all your args are explicit, i.e. not * or ** args. If you have some of those, change the code accordingly.
You may use default initialization, You should keep in mind the maximum number of variables that could be passed to this function. Then create a function with that number of parameters but initializing them with 0, because a+0 = a(in case some parameters are missing it will replace then with 0 which won't affect the results.)
def sum1(a=0, b=0, c=0, d=0):
return a+b+c+d
print sum1(1)
>>> 1
print sum1(1, 2)
>>> 3
print sum1(1, 2, 3)
>>> 6
print sum1(1, 2, 3, 4)
>>> 10
However, if you call the function with more than 4 arguments, it would raise error statement
Also as suggested by #CoryKramer in the comments you can also pass your varlist = [1, 2, 3, 4] as a parameter :
print sum1(*varlist)
>>> 10
Keeping in mind that the len(varlist) should be less than the number of parameters defined.
A general solution:
To get the number of argument, you can use f.func_code.co_argcount and than pass the correct elements from the list:
def sum2(x,y):
return x + y
def sum3(x,y,z):
return x + y + z
varlist = [2,5,4]
[f(*varlist[:f.func_code.co_argcount]) for f in [sum2,sum3]]
>> [7, 11]
You can check if f is a function with the is keyword
def sum2(x, y):
return x + y
def sum3(x, y, z):
return x + y + z
varList = [1, 2, 3]
f = sum2
if f is sum2:
sum = f(varList[0], varList[1])
print('Sum 2: ' + str(sum))
# Prints: 'Sum 2: 3'
f = sum3
if f is sum3:
sum = f(varList[0], varList[1], varList[2])
print('Sum 3: ' + str(sum))
# Prints: 'Sum 3: 6'
A dict of functions:
def two(l):
return l[0] + l[1]
def three(l):
return l[0] * l[1] + l[2]
funcs = {2:two, 3:three}
l = [1, 2, 3]
print len(l)
print funcs[len(l)](l)

Order of execution of tuples in Python during assignment [duplicate]

What is the difference between the following Python expressions:
# First:
x,y = y,x+y
# Second:
x = y
y = x+y
First gives different results than Second.
e.g.,
First:
>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3
Second:
>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4
y is 3 in First and 4 in Second
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. So,
x, y = y, x + y
evaluates y (let's call the result ham), evaluates x + y (call that spam), then sets x to ham and y to spam. I.e., it's like
ham = y
spam = x + y
x = ham
y = spam
By contrast,
x = y
y = x + y
sets x to y, then sets y to x (which == y) plus y, so it's equivalent to
x = y
y = y + y
It is explained in the docs in the section entitled "Evaluation order":
... while evaluating an assignment, the right-hand side is evaluated
before the left-hand side.
The first expression:
Creates a temporary tuple with value y,x+y
Assigned in to another temporary tuple
Extract the tuple to variables x and y
The second statement is actually two expressions, without the tuple usage.
The surprise is, the first expression is actually:
temp=x
x=y
y=temp+y
You can learn more about the usage of comma in "Parenthesized forms".
An observation regarding the left-hand side as well: the order of assignments is guaranteed to be the order of their appearance, in other words:
a, b = c, d
is equivalent functionally to precisely (besides t creation):
t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment
This matters in cases like object attribute assignment, e.g.:
class dummy:
def __init__(self): self.x = 0
a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"
a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
This also implies that you can do things like object creation and access using one-liners, e.g.:
class dummy:
def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5
I've recently started using Python and this "feature" baffled me. Although there are many answers given, I'll post my understanding anyway.
If I want to swap the values of two variables, in JavaScipt, I'd do the following:
var a = 0;
var b = 1;
var temp = a;
a = b;
b = temp;
I'd need a third variable to temporarily hold one of the values. A very straightforward swap wouldn't work, because both of the variables would end up with the same value.
var a = 0;
var b = 1;
a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1
Imagine having two different (red and blue) buckets and having two different liquids (water and oil) in them, respectively. Now, try to swap the buckets/liquids (water in blue, and oil in red bucket). You can't do it unless you have an extra bucket.
Python deals with this with a "cleaner" way/solution: Tuple Assignment.
a = 0
b = 1
print(a, b) # 0 1
# temp = a
# a = b
# b = temp
a, b = b, a # values are swapped
print(a, b) # 1 0
I guess, this way Python is creating the "temp" variables automatically and we don't have to worry about them.
In the second case, you assign x+y to x
In the first case, the second result (x+y) is assigned to y
This is why you obtain different results.
After your edit
This happen because, in the statement
x,y = y,x+y
all variables at the right member are evaluated and, then, are stored in the left members. So first proceed with right member, and second with the left member.
In the second statement
x = y
y = x + y
yo first evaluated y and assign it to x; in that way, the sum of x+y is equivalent to a sum of y+y and not of x+x wich is the first case.
The first one is a tuple-like assignment:
x,y = y,x+y
Where x is the first element of the tuple, and y is the second element, thus what you are doing is:
x = y
y = x+y
Wheras the second is doing a straight assign:
x=y
x=x+y
Other answers have already explained how it works, but I want to add a really concrete example.
x = 1
y = 2
x, y = y, x+y
In the last line, first the names are dereferenced like this:
x, y = 2, 1+2
Then the expression is evaluated:
x, y = 2, 3
Then the tuples are expanded and then the assignment happens, equivalent to:
x = 2; y = 3
For newbies, I came across this example that can help explain this:
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a+b
With the multiple assignment, set initial values as a=0, b=1.
In the while loop, both elements are assigned new values (hence called 'multiple' assignment). View it as (a,b) = (b,a+b). So a = b, b = a+b at each iteration of the loop. This continues while a<10.
RESULTS:
0
1
1
2
3
5
8
Let's grok the difference.
x, y = y, x + y
It's x tuple xssignment, mexns (x, y) = (y, x + y), just like (x, y) = (y, x)
Stxrt from x quick example:
x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1
When comes to (x, y) = (y, x + y)
ExFP, have x try directly
x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2
However,
In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5
The result is different from the first try.
Thx's because Python firstly evaluates the right-hand x+y
So it equivxlent to:
old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c
In summary, x, y = y, x+y means,
x exchanges to get old_value of y,
y exchanges to get the sum of old value x and old value y,
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b
Output
1
1
2
3
5
8
the variables a and b simultaneously get the new values 0 and 1, the same a, b = b, a+b, a and b are assigned simultaneously.

Python: function arguments and return values

Say I have a function
def equals_to(x,y):
a + b = c
def some_function(something):
for i in something:
...
Is there a way to use c that was calculated by equals_to as a parameter for some_function like this
equals_to(1,2)
some_function(c)
You need to return the value of c from the function.
def equals_to(x,y):
c = x + y # c = x + y not a + b = c
return c # return the value of c
def some_function(something):
for i in something:
...
return
sum = equals_to(1,2) # set sum to the return value from the function
some_function(sum) # pass sum to some_function
Also the function signature of equals_to takes the arguments x,y but in the function you use a,b and your assignment was the wrong way round, c takes the value of x + y not a + b equals c.
Strongly recommend: http://docs.python.org/2/tutorial/

Multiple assignment and evaluation order in Python

What is the difference between the following Python expressions:
# First:
x,y = y,x+y
# Second:
x = y
y = x+y
First gives different results than Second.
e.g.,
First:
>>> x = 1
>>> y = 2
>>> x,y = y,x+y
>>> x
2
>>> y
3
Second:
>>> x = 1
>>> y = 2
>>> x = y
>>> y = x+y
>>> x
2
>>> y
4
y is 3 in First and 4 in Second
In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. So,
x, y = y, x + y
evaluates y (let's call the result ham), evaluates x + y (call that spam), then sets x to ham and y to spam. I.e., it's like
ham = y
spam = x + y
x = ham
y = spam
By contrast,
x = y
y = x + y
sets x to y, then sets y to x (which == y) plus y, so it's equivalent to
x = y
y = y + y
It is explained in the docs in the section entitled "Evaluation order":
... while evaluating an assignment, the right-hand side is evaluated
before the left-hand side.
The first expression:
Creates a temporary tuple with value y,x+y
Assigned in to another temporary tuple
Extract the tuple to variables x and y
The second statement is actually two expressions, without the tuple usage.
The surprise is, the first expression is actually:
temp=x
x=y
y=temp+y
You can learn more about the usage of comma in "Parenthesized forms".
An observation regarding the left-hand side as well: the order of assignments is guaranteed to be the order of their appearance, in other words:
a, b = c, d
is equivalent functionally to precisely (besides t creation):
t = (c, d)
a = t[0] # done before 'b' assignment
b = t[1] # done after 'a' assignment
This matters in cases like object attribute assignment, e.g.:
class dummy:
def __init__(self): self.x = 0
a = dummy(); a_save = a
a.x, a = 5, dummy()
print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"
a = dummy(); a_save = a
a, a.x = dummy(), 5
print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
This also implies that you can do things like object creation and access using one-liners, e.g.:
class dummy:
def __init__(self): self.x = 0
# Create a = dummy() and assign 5 to a.x
a, a.x = dummy(), 5
I've recently started using Python and this "feature" baffled me. Although there are many answers given, I'll post my understanding anyway.
If I want to swap the values of two variables, in JavaScipt, I'd do the following:
var a = 0;
var b = 1;
var temp = a;
a = b;
b = temp;
I'd need a third variable to temporarily hold one of the values. A very straightforward swap wouldn't work, because both of the variables would end up with the same value.
var a = 0;
var b = 1;
a = b; // b = 1 => a = 1
b = a; // a = 1 => b = 1
Imagine having two different (red and blue) buckets and having two different liquids (water and oil) in them, respectively. Now, try to swap the buckets/liquids (water in blue, and oil in red bucket). You can't do it unless you have an extra bucket.
Python deals with this with a "cleaner" way/solution: Tuple Assignment.
a = 0
b = 1
print(a, b) # 0 1
# temp = a
# a = b
# b = temp
a, b = b, a # values are swapped
print(a, b) # 1 0
I guess, this way Python is creating the "temp" variables automatically and we don't have to worry about them.
In the second case, you assign x+y to x
In the first case, the second result (x+y) is assigned to y
This is why you obtain different results.
After your edit
This happen because, in the statement
x,y = y,x+y
all variables at the right member are evaluated and, then, are stored in the left members. So first proceed with right member, and second with the left member.
In the second statement
x = y
y = x + y
yo first evaluated y and assign it to x; in that way, the sum of x+y is equivalent to a sum of y+y and not of x+x wich is the first case.
The first one is a tuple-like assignment:
x,y = y,x+y
Where x is the first element of the tuple, and y is the second element, thus what you are doing is:
x = y
y = x+y
Wheras the second is doing a straight assign:
x=y
x=x+y
Other answers have already explained how it works, but I want to add a really concrete example.
x = 1
y = 2
x, y = y, x+y
In the last line, first the names are dereferenced like this:
x, y = 2, 1+2
Then the expression is evaluated:
x, y = 2, 3
Then the tuples are expanded and then the assignment happens, equivalent to:
x = 2; y = 3
For newbies, I came across this example that can help explain this:
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a+b
With the multiple assignment, set initial values as a=0, b=1.
In the while loop, both elements are assigned new values (hence called 'multiple' assignment). View it as (a,b) = (b,a+b). So a = b, b = a+b at each iteration of the loop. This continues while a<10.
RESULTS:
0
1
1
2
3
5
8
Let's grok the difference.
x, y = y, x + y
It's x tuple xssignment, mexns (x, y) = (y, x + y), just like (x, y) = (y, x)
Stxrt from x quick example:
x, y = 0, 1
#equivxlent to
(x, y) = (0, 1)
#implement xs
x = 0
y = 1
When comes to (x, y) = (y, x + y)
ExFP, have x try directly
x, y = 0, 1
x = y #x=y=1
y = x + y #y=1+1
#output
In [87]: x
Out[87]: 1
In [88]: y
Out[88]: 2
However,
In [93]: x, y = y, x+y
In [94]: x
Out[94]: 3
In [95]: y
Out[95]: 5
The result is different from the first try.
Thx's because Python firstly evaluates the right-hand x+y
So it equivxlent to:
old_x = x
old_y = y
c = old_x + old_y
x = old_y
y = c
In summary, x, y = y, x+y means,
x exchanges to get old_value of y,
y exchanges to get the sum of old value x and old value y,
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b
Output
1
1
2
3
5
8
the variables a and b simultaneously get the new values 0 and 1, the same a, b = b, a+b, a and b are assigned simultaneously.

Categories

Resources