Why does swapping fail in python? - python-3.x

I was trying to write a program that would reverse a list in python3. I first tried:
def reverse(lst):
""" Reverses lst in place.
>>> x = [3, 2, 4, 5, 1]
>>> reverse(x)
>>> x
[1, 5, 4, 2, 3]
"""
n = len(lst)
for i in range(n//2):
lst[i], lst[n-i-1] = lst[n-i-1], lst[i]
It failed and the x I got was the original value. However, when I changed my code to this, it worked:
def reverse(lst):
""" Reverses lst in place.
>>> x = [3, 2, 4, 5, 1]
>>> reverse(x)
>>> x
[1, 5, 4, 2, 3]
"""
n = len(lst)
for i in range(n//2):
temp = lst[i]
lst[i] = lst[n-i-1]
lst[n-i-1] = temp

It works as expected:
>>> def reverse(lst):
... n = len(lst)
... for i in range(n//2):
... lst[i], lst[n-i-1] = lst[n-i-1], lst[i]
...
>>> lst = [1,2,3,4,5]
>>> reverse(lst)
>>> print(lst)
[5, 4, 3, 2, 1]
BTW, why don't you use list.reverse?
>>> lst = [1,2,3]
>>> lst.reverse()
>>> lst
[3, 2, 1]

Related

Python Array Intersection

This is my code to find values common between 2 arrays.
li1 = [int(x) for x in input().split()]
li2 = [int(h) for h in input().split()]
for m in li1 :
for j in li2 :
if m == j :
print(m, end=" ")
j = float("-inf")
break
When I do li1 = [5, 5, 5] and li2 = [5, 5], it returns 5 5 5. I want this to be 5 as li2 only has two 5. How can I do this.
You can do the same more simply by using sets and intersection:
li1 = [1, 2, 3]
li2 = [2, 3, 4]
shared = list(set(li1).intersection(set(li2))
print(shared) # prints [2, 3]

How do I un-shuffle a list back to its original form

How would I undo the shuffle I have done on alist and bring it back to its original sequence:
[1, 2, 3 , 4]
import random
alist = [1, 2, 3, 4]
random.shuffle(alist) # alist is randomly shuffled
I just took this answer from A good way to shuffle and then unshuffle a python list question's accepted answer and did the small change to it. It's working perfect and please refer #trincot and #canton7 answers for more information, they are very educated.
import random
def getperm(l):
seed = sum(l)
random.seed(seed)
perm = list(range(len(l)))
random.shuffle(perm)
random.seed() # optional, in order to not impact other code based on random
return perm
def shuffle(l): # [1, 2, 3, 4]
perm = getperm(l) # [3, 2, 1, 0]
l[:] = [l[j] for j in perm] # [4, 3, 2, 1]
def unshuffle(l): # [4, 3, 2, 1]
perm = getperm(l) # [3, 2, 1, 0]
res = [None] * len(l) # [None, None, None, None]
for i, j in enumerate(perm):
res[j] = l[i]
l[:] = res # [1, 2, 3, 4]
alist = [1, 2, 3, 4]
print(alist) # [1, 2, 3, 4]
shuffle(alist)
print(alist) # shuffled, [4, 3, 2, 1]
unshuffle(alist)
print(alist) # the original, [1, 2, 3, 4]
random.shuffle shuffles the input sequence in-place. To get back the original list, you need to keep a copy of it.
# make a copy
temp = alist[:]
# shuffle
random.shuffle(alist)
# alist is now shuffled in-place
# restore from the copy
alist = temp

how to convert the following code into list comprehensions

I have written the code using for loop, i want the code into list comprehension.
mainLst = [[2],[3],[4],[5],[6],[7],[8]]
lst2 = [[],[],[],[]]
const = 0
for i in range(4):
k = const
for j in range(4):
lst2[const].append(mainLst[k][0])
k += 1
const += 1
print(lst2)
Expecting the above code into list comprehension.
If you want to transform just a loop part and still use mainLst variable, then it will look like:
mainLst = [[2],[3],[4],[5],[6],[7],[8]]
lst2 = [[mainLst[j + k][0] for k in range(4)] for j in range(4)]
print(lst2)
# or if you still want to have initialized lst2 array, then:
lst2 = [[],[],[],[]]
[lst2[j].extend([mainLst[j + k][0] for k in range(4)]) for j in range(4)]
print(lst2)
Both output the same:
[[2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]
Can be done without creating other variables like k and const
lst2 = [[i for i in range(j, j + 4)] for j in range(2, 6)]
You can use the operator itemgetter with slice to get slices of sublists from the list and chain.from_iterable to merge sublists into one list:
from operator import itemgetter
from itertools import chain
mainLst = [[2],[3],[4],[5],[6],[7],[8]]
[list(chain.from_iterable(itemgetter(slice(i, i + 4))(mainLst))) for i in range(4)]
# [[2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]

Random change of rows of two matrices using indices

Any idea or clue about writing below problem code in python 3.6?
Imagine I have matrix A and B as below:
A = [1 2, 3 4, 5 6] with the dimension of 3*2
B = [1, 3, 5] with the dimension of 3*1
Now I want to change the rows randomly using indices.
for instance index 1 related to [1 2] from A and [1] from B, index 2 related to [3 4] from A and [3] from B, index 3 related to [5 6] from A and [5] from B.
Imagine randomly I order the indices as 2, 3, 1, now my output will be:
A=[3 4, 5 6, 1 2]
B=[3, 5, 1]
import numpy as np
A = [[1, 2],[3, 4], [5, 6]]
A = np.array(A)
B = [[1], [3], [5]]
B = np.array(B)
import random
def rand(n):
l = list(range(n))
random.shuffle(l)
l = np.reshape(l, (n,1)) return l l = rand(3)
print(l)
AF = []
AFF = []
BF = []
BFF = []
for i in range (0, len(A)):
AF = A[l[i]]
AFF.extend(AF)
BF = B[l[i]]
BFF.extend(BF)
B = np.array(BFF)
A = np.array(AFF)
print(B)
print(A)

How do you update a local class variable in Python in a backtracking loop?

I am trying to append permutations of a list of integers to a local variable in python but end of appending a single permutation several times. The code will print all the results correctly but not sure why my class variable will not be updated correctly.
Any help would be extremely appreciated!!
I am working on a leetCode problem but can't output the right results. I am trying to update my array, myVals, within a backtracking loop but and storing the just one permutation.
I can print all the results however when
class Solution:
def __init__(self):
self.myVals = []
def add(self, x):
self.myVals.append(x)
def permuteArray(self, nums, l, r):
if l == r:
print(nums)
self.add(nums)
else:
for i in range(l, r + 1):
nums[l], nums[i] = nums[i], nums[l]
self.permuteArray(nums, 1+l, r)
nums[l], nums[i] = nums[i], nums[l]
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
numCount = len(nums)
start = 0
self.permuteArray(nums, start, numCount - 1)
print(self.myVals)
nums = [1,2,3]
driver = Solution()
result = driver.permute(nums)
Expected Results:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]
Actual Results:
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]

Resources