I made some python code to get all subset by recursive.
if given a data
data = [1,2,3,4,5]
length = 3
the result will print all subset at 3 length like this
1,2,3
1,2,4
1,2,5
2,3,4
2,3,5...
this is my code
data = [1,2,3,4,5]
n = 5
r = 3
templist = []
def re(max,length,idx):
if idx == max:
return
if idx == length:
for i in templist:
print(" "+str(i))
print("\n")
return
else:
templist.append(data[idx])
re(max,length,idx+1)
templist.pop()
re(max,length,idx+1)
if __name__ == "__main__":
re(n,r,0)
my expectaion it loop all the possible subset
but it will fail when it encouter call
re(max,length,idx+1)
after
temlist.pop()
when code enter the second re()
function
I expected it append templist.append(data[4])
because first re()
function return by if condition
if idx == length:
when idx
is 3, idx
is the same the length(3).
so the recursive end,run temlist.pop()
and
it will enter the second re(4)
function
because I coded idx+1
but it will fail
idx
only be circled between 2~3
so I changed second recursive function
re(max,length,idx+1)
to
re(max,length,idx+2)
and I totally broken.
I think the logic I made was bascally wrong. but I don't know where to fix it how can I solve to call recursive as I expected?
Here is how:
def func(data, length, lst=[]):
for i in data[length - 1:]:
lst.append(data[:length - 1] + [i])
if data:
func(data[1:], length, lst)
return lst
data = [1,2,3,4,5]
length = 3
print(func(data, length))
Output:
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [2, 3, 4], [2, 3, 5], [3, 4, 5]]
Explanation:
Define a function that takes in three parameters, the list (data
), the length (length
) and an empty list (lst
) to store the output values (defining it outside the function is considered bad practice).
Iterate through the elements of the data
list besides the first length - 1
indexed elements, and append the elements from the 0
index to the length - 1
index plus the current element of the iteration.
If the data
list didn't go empty, call the current function again, but using the slice [1:]
to remove the first character.
If the data
list didn go empty, return the lst
list.
Your other option is to use Python's powerful generators. Using this technique, we no longer need the lst
parameter -
def func(data, length):
for i in data[length - 1:]:
yield data[:length - 1] + [i]
if data:
yield from func(data[1:], length)
Now we can retrieve the permutations using iteration -
data = [1,2,3,4,5]
length = 3
for perm in func(data, length):
print(perm)
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[2, 3, 4]
[2, 3, 5]
[3, 4, 5]
Or we can gather all permutations in a list
-
data = [1,2,3,4,5]
length = 3
print(list(func(data, length)))
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [2, 3, 4], [2, 3, 5], [3, 4, 5]]