For loop not updating the list - python

Main code:
for i in Pool:
print(i)
while(i[0] != 1):
print('i is ' + str(i))
i=rotate(i)
print('after rotate i is ' + str(i))
print(Pool)
Rotate Function:
def rotate(a):
a= a[1:]+a[:1]
return a
Result:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
i is [2, 1, 3]
after rotate i is [1, 3, 2]
[2, 3, 1]
i is [2, 3, 1]
after rotate i is [3, 1, 2]
i is [3, 1, 2]
after rotate i is [1, 2, 3]
[3, 1, 2]
i is [3, 1, 2]
after rotate i is [1, 2, 3]
[3, 2, 1]
i is [3, 2, 1]
after rotate i is [2, 1, 3]
i is [2, 1, 3]
after rotate i is [1, 3, 2]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
From this code, Pool = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
I can see my rotate function works and rotates 3,2,1 to 2,1,3 but it is not updated to the pool. The result I want is [[1, 2, 3], [1, 3, 2], [1, 3, 2], [1, 2, 3], [1, 2, 3], [1, 3, 2]]

You're creating a new list, rather than rotating it in place.
To rotate a list in place, use a[:] = a[1:] + a[:1]; you can then also omit the return (and it's probably better style to omit it).
def rotate(a):
""" Rotate the list in-place """
a[:] = a[1:] + a[:1]
You then call this function without using the return value (which will be None):
for i in Pool:
while i[0] != 1:
rotate(i)

Pool = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
def rotate(a):
a = a[1:] + a[:1]
return a
new_pool = []
for i in Pool:
while i[0] != 1:
print('i is ' + str(i))
i = rotate(i)
print('after rotate i is ' + str(i))
new_pool.append(i)
print(Pool)
print(new_pool)

You need to update Pool by using Pool[index] = i, I'm guessing after the second loop.
Example:
Pool = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
def rotate(i):
return i[1:]+i[:1]
print(Pool)
for index,i in enumerate(Pool):
print(i)
while (i[0] != 1):
print('i is ' + str(i))
i = rotate(i)
print('after rotate i is ' + str(i))
Pool[index] = i
print(Pool)

Related

how to merge lists in list (without numpy)

This is what i have-
def merge_list(mylist)
list1 = []
one_len = len(mylist)
two_len = len(mylist[0][0])
for index in range(two_len):
combine_list = []
for index2 in range(one_len):
combine_list.extend([a[index] for a in mylist[
index2]])
list1.append(combine_list)
return list1
But i have a problem with the output-
for example:
input-
mylist=[[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]], [[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]], [[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]]]
in short-
[[[1]*3]*4, [[2]*3]*4, [[3]*3]*4]
the output is -
[[[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]]]
and not -
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]]]
in short-
[[[1, 2, 3]]*3]*4
I would be happy to solve the problem and advise how to shorten the code.
In order to fix your code, you just need to update the return statement like this:
return [list1]
Though there is still a hidden problem when your inner lists lengths are longer than one element. Check your outputs with sample inputs like [[[2,1], [3,1]]].
One further - more compact - solution may be obtained by concatenating the inner lists within a cycle, then recreate the number of dimensions you need, moving the complexity from O(n^2) to O(n).
mylist = [[[2,1]],[[3,1]]]
def merge_list(mylist):
l_out = []
for l in mylist:
l_out += l[0]
return [[l_out]]
EDIT: In case of more complex inputs, you can extract first all elements and eventually fix the dimensions. This will still bring O(n^2) complexity though:
def merge_list(lst):
elements = [[] for _ in range(len(mylist[0]))]
for l1 in mylist:
for idx, l2 in enumerate(l1):
elements[idx] += l2
return [elements]
merge_list(mylist)
Input:
[[[1], [1]], [[2], [2]], [[3], [3]]]
Output:
[[[1, 2, 3], [1, 2, 3]]]

Python recursive function wont change list defined in main()

Here I wrote a recursive function to find the permutation of a list.
def backtrack(arr,tmp):
if len(tmp)==len(arr):
res.append(tmp)
#==print res here==
print(res)
else:
for i in range(len(arr)):
if arr[i] in tmp: continue
tmp.append(arr[i])
backtrack(arr,tmp)
tmp.pop()
if __name__ == '__main__':
points=[1,2,3]
res=[]
tmp=[]
backtrack(points,tmp)
print(res)
#code result
#[[1, 3, 2], [1, 3, 2]]
#[[2, 1, 3], [2, 1, 3], [2, 1, 3]]
#[[2, 3, 1], [2, 3, 1], [2, 3, 1], [2, 3, 1]]
#[[3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2]]
#[[3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1]]
#[[], [], [], [], [], []]
I have no idea why the list 'res' defined in main() wont be updated when we pass it to a recursive function. Any suggestion about how to update 'res'?
When you do:
res.append(tmp)
you are appending to the global list res a reference to the list tmp. Any future changes to tmp will be visible through res as it just contains multiple references to the same tmp list.
Instead you probably want to append a copy of tmp:
res.append(list(tmp))
Make that change and your output is now:
[[1, 2, 3]]
[[1, 2, 3], [1, 3, 2]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
Alternatively you could convert the tmp list into a tuple:
res.append(tuple(tmp))
If you do that the option is then identical to the output returned by itertools.permutations:
>>> import itertools
>>> list(itertools.permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

Python 3 list of all possible cohesive combinations

Hi I'm trying to make a list of all possible cohesive combinations of another list, so from [0, 1, 2, 3] I'd like to get [[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]. So far I've got this:
def expandArray(arr):
result = []
for x in range(0, len(arr)):
subArray = [arr[x]]
result.append(subArray)
for y in range(x + 1, len(arr)):
subArray.append(arr[y])
result.append(subArray)
return(result)
But this returns: [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [2, 3], [2, 3], [3]].
What am I doing wrong ?
subArray is a list that you modify in your for loop. When you append to it, you do not create a new list, but you modify it, and then put it in the list again, so will in the end get a result with several copies of the same list. Compare this code:
a = []
b = [5]
a.append(b)
b.append(1)
a.append(b)
print(a)
would output:
[[5, 1], [5, 1]]
Here is a way to have your desired output using list slicing:
def get_combs(iterable):
for k, _ in enumerate(iterable):
elm = k
while elm <= len(iterable):
data = iterable[k:elm]
elm += 1
if data:
yield data
combs = list(get_combs([0, 1, 2, 3]))
print(combs)
Output:
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]

Code not returning permutations

I have written python code to permute a list of numbers.
class Solution:
def __init__(self):
self.permutations = []
def permute_helper(self, nums, chosen):
if nums == []:
print chosen
self.permutations.append(chosen)
else:
for num in nums:
#choose
chosen.append(num)
temp = nums[:]
temp.remove(num)
#explore
self.permute_helper(temp, chosen)
#un-choose
chosen.remove(num)
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
self.permute_helper(nums, [])
return self.permutations
s = Solution()
input = [1,2,3]
print s.permute(input)
It returns:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
[[], [], [], [], [], []]
I want all the permutations to appear in the returned list like this
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
I think it has something to do with scoping but I have no idea what I've done wrong to make the list returning nothing.
When you append chosen to self.permutations, any change you make to chosen after the fact will also affect each element of self.permutations. By calling chosen.remove later, you remove numbers from self.permutations as well. Consider this simpler example:
>>> a = [1,2,3]
>>> b = []
>>> b.append(a)
>>> b.append(a)
>>> b.append(a)
>>> a.remove(2)
>>> b
[[1, 3], [1, 3], [1, 3]]
You could append a shallow copy of chosen to self.permutations instead, in which case changes made to chosen afterwards will have no effect on self.permutations.
if nums == []:
print chosen
self.permutations.append(chosen[:])
Result:
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

Transposing a nxn Matrix in Python using only for/while loops

I wanted to know why the solution I have written doesn't work:
def transpose(sudoku):
n = len(sudoku)
l_tr = [0]*n
k = 0
tr_sudoku = [0]*n
while k < n:
tr_sudoku[k] = l_tr
k = k+1
i = 0
for i in range(len(sudoku)):
j = 0
for j in range(len(sudoku)):
tr_sudoku[i][j] = sudoku[j][i]
print j, i, tr_sudoku, sudoku[i][j]
print tr_sudoku
return tr_sudoku
correct = [[1,2,3],[2,3,1],[3,1,2]]
print transpose(correct)
It outputs the following incorrect solution:
0 0 [[1, 0, 0], [1, 0, 0], [1, 0, 0]] 1
1 0 [[1, 2, 0], [1, 2, 0], [1, 2, 0]] 2
2 0 [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 3
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
0 1 [[2, 2, 3], [2, 2, 3], [2, 2, 3]] 2
1 1 [[2, 3, 3], [2, 3, 3], [2, 3, 3]] 3
2 1 [[2, 3, 1], [2, 3, 1], [2, 3, 1]] 1
[[2, 3, 1], [2, 3, 1], [2, 3, 1]]
0 2 [[3, 3, 1], [3, 3, 1], [3, 3, 1]] 3
1 2 [[3, 1, 1], [3, 1, 1], [3, 1, 1]] 1
2 2 [[3, 1, 2], [3, 1, 2], [3, 1, 2]] 2
[[3, 1, 2], [3, 1, 2], [3, 1, 2]]
[[3, 1, 2], [3, 1, 2], [3, 1, 2]]
Help would be appreciated! Thanks.
The ideal correct solution to:
correct = [[1,2,4],[2,3,4],[3,4,2]]
would be:
tr_correct = [[1,2,3],[2,3,4],[4,4,2]]
You can easily transpose with zip:
def transpose(sudoku):
return list(map(list, zip(*sudoku)))
Example output:
>>> correct = [[1,2,3],[2,3,1],[3,1,2]]
>>> transpose(correct)
[[1, 2, 3], [2, 3, 1], [3, 1, 2]]
The easiest "manual" way is to switch rows and columns:
def transpose_manually(sudoku):
output = sudoku[:] # new grid the same size
for r in range(len(sudoku)): # each row
for c in range(len(sudoku[0])): # each column
output[c][r] = sudoku[r][c] # switch
return output

Categories

Resources