Code not returning permutations - python

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]]

Related

How to make a recursive function to generate the combination of numbers eg. for n=3, (1,1,1),(1,1,2) and so on?

def generate(n):
t=[]
lol=[[] for i in range(n**n)]
helper(n,t,lol)
return(lol)
def helper(n,t,lol):
global j
if len(t)==n:
lol[j]=lol[j]+t
j += 1
return
for i in range(1,n+1):
print(i)
t.append(i)
helper(n,t,lol)
t.pop()
j=0
print(generate(2))
print(generate(3))
Here, for n=2, i'm getting expected answer.
But for, n=3, it is showing Index Error:
in helper
lol[j]=lol[j]+t
IndexError: list index out of range
Try this code:
def generate(n):
def helper(m, n, s):
if m==0:
print(s)
else:
for x in range(1,n+1):
helper(m-1, n, s+[x])
assert n>=1
helper(n, n, [])
Examples:
>>> generate(1)
[1]
>>> generate(2)
[1, 1]
[1, 2]
[2, 1]
[2, 2]
>>> generate(3)
[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 2, 1]
[1, 2, 2]
[1, 2, 3]
[1, 3, 1]
[1, 3, 2]
[1, 3, 3]
[2, 1, 1]
[2, 1, 2]
[2, 1, 3]
[2, 2, 1]
[2, 2, 2]
[2, 2, 3]
[2, 3, 1]
[2, 3, 2]
[2, 3, 3]
[3, 1, 1]
[3, 1, 2]
[3, 1, 3]
[3, 2, 1]
[3, 2, 2]
[3, 2, 3]
[3, 3, 1]
[3, 3, 2]
[3, 3, 3]
>>>

Create a matrix in Python with sequences increasing

I am working on a project and I need to be able to create a function that takes in a value (n) and returns a matrix with increasing values.
ex: Given x = 2, return = [[1],[1, 2]]
Given x = 5, return = [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4],[1, 2, 3, 4, 5]]
Below is what I have thus far:
def matrixIncrease(n):
lst = []
for i in range(n):
lst.append([])
for j in range(0, n):
lst[i].append(j)
return lst
print(matrixIncrease(3))
This will just return
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
So it looks like the correct amount of inner list are being created. But, the values inside the list are not increasing correctly. Any suggestions?
Maybe you could try this List Comprehension way:
It's quite self-explnatory in the code, just play/experiment with different i and j to see the effects of changes...
Basically the j is to iterate and increase the numbers in each loop.
def create_sub(n):
''' create n sub_lists: each list has increasing items:
[1], [1, 2], [1, 2, 3], .... [1, ... n] '''
sub_matrix = [[j +1 for j in range(0, i)] # j - for col values
for i in range(1, n + 1)] # i - control rows
return sub_matrix
>>>create_sub(5)
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
>>>create_sub(8)
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8]]
You could try this:
all_ = []
def matrixIncrease(n):
if n == 1:
all_.append([1])
return[1]
j=[]
for i in range(1,n+1):
j.append(i)
matrixIncrease(n-1)
all_.append(j)
matrixIncrease(7)
print(all_)

How to reorder a list composed of lists

I am trying to tranform
[[1, 2, 3], [1, 2]]
into
[[1, 2, 3], [3, 2, 1], [2, 3, 1], [1, 2], [2, 1]]
But instead of the correct output, I am getting this:
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2], [1, 2]]
Here is my code
def listReorder(list1):
List2 = []
for list in list1:
listTemp = list
for item in list:
List2.append(listTemp)
t=listTemp.pop()
listTemp.insert(0, t)
return List2
List = [[1, 2, 3], [1, 2]]
listReorder(List)
In your for loop, you are adding the same list again and again, but instead, you should make a copy of the list in the iteration.
def listReorder(list1):
List2 = []
for list in list1:
listTemp = list
for item in list:
List2.append([x for x in listTemp])
t=listTemp.pop()
listTemp.insert(0, t)
return List2
List = [[1, 2, 3], [1, 2]]
listReorder(List)
Output:
[[1, 2, 3], [3, 1, 2], [2, 3, 1], [1, 2], [2, 1]]

For loop not updating the list

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)

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]]

Categories

Resources