How does in-place operation of list work - python-3.x

This is my code:
x=[1,3,2]
def foo(x):
x.sort()
x = x + [4,5]
x.extend([6,7])
return x
foo(x)
print(x)
i expect the printed list to be [1,2,3,4,5,6,7] but i got [1,2,3] instead. I read that this is due to in-place operation because it returns None, but ive included return x into my code but it still does not work.

There are two issues here: the scope of x, and the return value.
When you declare x = x + [4, 5], x isn't the same list anymore
>>> x = [1, 2, 3]
>>> id(x)
4501926472
>>> x = x + [4, 5]
>>> id(x)
4501926616
>>>
Thus, x inside foo refers to a local x, not the global x defined outside of the function.
Furthermore, you do not store the return x from foo, so it disappears, for all practical purposes.

You have to tell python to print the returned value of x after the foo method is executed , you told python to print x , witch you defined as x=[1,3,2] , you have to print the value of x after it goes through the foo method
x=[1,3,2]
def foo(x):
x.sort()
x = x + [4,5]
x.extend([6,7])
return x
print(foo(x))

Related

Python 3+: How to return for loop output value to function

I want to assign value to function of below code:
def adds(y):
for i in y:
z = i + 1
print(z)
x = [1, 2, 3]
adds(x)
output:
2
3
4
But when i tried to assigned the result to function with creating instance such:
# print(z) commented
p = adds(x)
print(p)
output:
None
expected output:
2
3
4
gives the return inside for loop gives output: 2
gives the return inside function block or set variable z to global inside the for loop block, and recall it in the outside gives same output: 4
How do to achieve the expected output: 2 3 4, from the return value to function of above code
As the function is printing the result, so no need to store the function value add(z) in variable so can return the value in function by using (return z) in function, Then you can store in a variable and print it.
Thanks
from
https://stackoverflow.com/a/39366192/18980456
def adds(y):
z = [i + 1 for i in y]
return z
x = [1, 2, 3]
p = adds(x)
print(p)

Shuffling a deck of cards with Python [duplicate]

In Python, I've seen two variable values swapped using this syntax:
left, right = right, left
Is this considered the standard way to swap two variable values or is there some other means by which two variables are by convention most usually swapped?
Python evaluates expressions from left to right. Notice that while
evaluating an assignment, the right-hand side is evaluated before the
left-hand side.
Python docs: Evaluation order
That means the following for the expression a,b = b,a :
The right-hand side b,a is evaluated, that is to say, a tuple of two elements is created in the memory. The two elements are the objects designated by the identifiers b and a, that were existing before the instruction is encountered during the execution of the program.
Just after the creation of this tuple, no assignment of this tuple object has still been made, but it doesn't matter, Python internally knows where it is.
Then, the left-hand side is evaluated, that is to say, the tuple is assigned to the left-hand side.
As the left-hand side is composed of two identifiers, the tuple is unpacked in order that the first identifier a be assigned to the first element of the tuple (which is the object that was formerly b before the swap because it had name b)
and the second identifier b is assigned to the second element of the tuple (which is the object that was formerly a before the swap because its identifiers was a)
This mechanism has effectively swapped the objects assigned to the identifiers a and b
So, to answer your question: YES, it's the standard way to swap two identifiers on two objects.
By the way, the objects are not variables, they are objects.
That is the standard way to swap two variables, yes.
I know three ways to swap variables, but a, b = b, a is the simplest. There is
XOR (for integers)
x = x ^ y
y = y ^ x
x = x ^ y
Or concisely,
x ^= y
y ^= x
x ^= y
Temporary variable
w = x
x = y
y = w
del w
Tuple swap
x, y = y, x
I would not say it is a standard way to swap because it will cause some unexpected errors.
nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]
nums[i] will be modified first and then affect the second variable nums[nums[i] - 1].
Does not work for multidimensional arrays, because references are used here.
import numpy as np
# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)
# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)
See also Swap slices of Numpy arrays
To get around the problems explained by eyquem, you could use the copy module to return a tuple containing (reversed) copies of the values, via a function:
from copy import copy
def swapper(x, y):
return (copy(y), copy(x))
Same function as a lambda:
swapper = lambda x, y: (copy(y), copy(x))
Then, assign those to the desired names, like this:
x, y = swapper(y, x)
NOTE: if you wanted to you could import/use deepcopy instead of copy.
That syntax is a standard way to swap variables. However, we need to be careful of the order when dealing with elements that are modified and then used in subsequent storage elements of the swap.
Using arrays with a direct index is fine. For example:
def swap_indexes(A, i1, i2):
A[i1], A[i2] = A[i2], A[i1]
print('A[i1]=', A[i1], 'A[i2]=', A[i2])
return A
A = [0, 1, 2, 3, 4]
print('For A=', A)
print('swap indexes 1, 3:', swap_indexes(A, 1, 3))
Gives us:
('For A=', [0, 1, 2, 3, 4])
('A[i1]=', 3, 'A[i2]=', 1)
('swap indexes 1, 3:', [0, 3, 2, 1, 4])
However, if we change the left first element and use it in the left second element as an index, this causes a bad swap.
def good_swap(P, i2):
j = P[i2]
#Below is correct, because P[i2] is modified after it is used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[P[i2]], P[i2] = P[i2], P[P[i2]]
print('Good swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
def bad_swap(P, i2):
j = P[i2]
#Below is wrong, because P[i2] is modified and then used in P[P[i2]]
print('Before: P[i2]=', P[i2], 'P[P[i2]]=', P[j])
P[i2], P[P[i2]] = P[P[i2]], P[i2]
print('Bad swap: After P[i2]=', P[i2], 'P[P[i2]]=', P[j])
return P
P = [1, 2, 3, 4, 5]
print('For P=', P)
print('good swap with index 2:', good_swap(P, 2))
print('------')
P = [1, 2, 3, 4, 5]
print('bad swap with index 2:', bad_swap(P, 2))
('For P=', [1, 2, 3, 4, 5])
('Before: P[i2]=', 3, 'P[P[i2]]=', 4)
('Good swap: After P[i2]=', 4, 'P[P[i2]]=', 3)
('good swap with index 2:', [1, 2, 4, 3, 5])
('Before: P[i2]=', 3, 'P[P[i2]]=', 4)
('Bad swap: After P[i2]=', 4, 'P[P[i2]]=', 4)
('bad swap with index 2:', [1, 2, 4, 4, 3])
The bad swap is incorrect because P[i2] is 3 and we expect P[P[i2]] to be P[3]. However, P[i2] is changed to 4 first, so the subsequent P[P[i2]] becomes P[4], which overwrites the 4th element rather than the 3rd element.
The above scenario is used in permutations. A simpler good swap and bad swap would be:
#good swap:
P[j], j = j, P[j]
#bad swap:
j, P[j] = P[j], j
You can combine tuple and XOR swaps: x, y = x ^ x ^ y, x ^ y ^ y
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
x, y = x ^ x ^ y, x ^ y ^ y
print('After swapping: x = %s, y = %s '%(x,y))
or
x, y = 10, 20
print('Before swapping: x = %s, y = %s '%(x,y))
print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))
Using lambda:
x, y = 10, 20
print('Before swapping: x = %s, y = %s' % (x, y))
swapper = lambda x, y : ((x ^ x ^ y), (x ^ y ^ y))
print('After swapping: x = %s, y = %s ' % swapper(x, y))
Output:
Before swapping: x = 10 , y = 20
After swapping: x = 20 , y = 10

Python iterating through pair of values in list for function

I have a list like
cases = [(1,1), (2,2), (3,3)]
trying to write a function that calculates through each item and return values:
def case_cal(cases)
for x, y in cases:
result = x+y
return result
output = case_cal(cases)
print(output)
I like to get output like
2
4
6
But I only get
2
I am a newbie learning python and something simple I am missing here. Could I get any advice? Thanks in advance!
Once you return something you move out of the function. So make a list, append your values to the list and then return in the end.
def case_cal(cases):
ret_values = []
for x, y in cases:
result = x+y
ret_values.append(result)
return ret_values
output = case_cal(cases)
print(*output)
Your code returns inside the for loop, at the end of the first iteration, so you'll only see the first x + y result.
This is a perfect use for a generator, which will allow you to grab the next x + y calculation on demand and offer maximum control over what the caller can do with the result:
cases = [(1,1), (2,2), (3,3)]
def case_cal(cases):
for x, y in cases:
yield x + y
for x in case_cal(cases):
print(x)
Output:
2
4
6
You can simply map the items of the list to the sum function:
list(map(sum, cases))
This becomes:
[2, 4, 6]
Or if you want to print the items individually:
for s in map(sum, cases):
print(s)
This outputs:
2
4
6
If you dont need the values in a list you can procced as follows:
cases = [(1,1), (2,2), (3,3)]
def case_cal(cases):
for x, y in cases:
result = x+y
print(result)
case_cal(cases)
Just directly print the values instead of returning them as once you return something you move out of the function.
Also,
cases = [(1,1), (2,2), (3,3)]
def case_cal(cases):
for x, y in cases:
print(x+y)
case_cal(cases)
You could do this:
cases = [(1,1), (2,2), (3,3)]
def case_cal(cases):
results = []
for x, y in cases:
results.append(x + y)
return results
output = [case_cal(cases)]
print(output)
And then you could define a print function like this:
def print_cases(cases):
for elem in cases[0]:
print(elem)
But there is a more Pythonic way:
def case_cal(cases):
return [(x + y) for (x, y) in cases]
This is called a list comprehension, and you are going to be using them very often in python. You can read more about them here.
Simply do the following:
def case_calc(cases):
for x, y in cases:
print(x + y)
case_calc([(1, 1), (2, 2), (3, 3)])
Cheers

Perplexed over a simple function in Python

Look at the code below:
def foo (x):
print("foo environment: x = {0}".format(x))
def bar (z, x = 0):
print("bar environment: z = {0} and x = {1}. Value to be returned: {2}".format(z, x, x+z))
return z + x
return bar(3)
foo(5)
foo environment: x = 5
bar environment: z = 3 and x = 0. Value to be returned: 3
3
Since in the foo environment x = 5, why bar uses the value 0?
You are only passing one argument here:
return bar(3)
The bar function accepts two values, one z and one x (x has a default value (0) and that is why only 1 argument is enough). By only passing the z, x=0.
Try this, and see what happens:
return bar(3, x)

How to use exponents under special criteria

I am new to python and was trying to find a way to organize a specific function so I can take a list, apply special criteria to it, and then return another list.
I want to:
1) square a number if it is even
2) cube a number if it is odd
3) and then store those results in a list and return that list
Here is my code:
def square_function(x):
if i % 2 == 0:
x = [i ** (2)]
else:
y = [i ** (3)]
func = [x, y]
return func
I am very new to programming with python so any help you can give would be fantastic.
take a list - apply special criteria to it - and then return another list.
You're looking for the map() function
def foo(x):
return x**2 if x%2==0 else x**3
l = [1,2,3]
I = list(map(foo, l))
Using list comprehension:
>>> a = [1,2,3,4,5]
>>> [x ** 2 if x % 2 == 0 else x ** 3 for x in a]
[1, 4, 27, 16, 125]
I think that this could be what you are looking for:
from math import sqrt
def square_or_cube_function(x):
result = []
for i in x:
if i % 2 == 0:
result.append(sqrt(i))
else:
result.append(i ** 3)
return result
print(square_or_cube_function([1, 4, 5, 8]))
print(square_or_cube_function([5, 7, 16, 32]))
OUTPUT:
[1, 2.0, 125, 2.8284271247461903]
[125, 343, 4.0, 5.656854249492381]
A shorter solution could be:
from math import sqrt
def square_or_cube_function(x):
return [sqrt(i) if i % 2 == 0 else i **3 for i in x]
print(square_or_cube_function([1, 4, 5, 8]))
print(square_or_cube_function([5, 7, 16, 32]))
Same output.
Another LC solution, but using a bit of cleverness:
[x ** (x % 2 + 2) for x in L]

Resources