I have a function get_appendable_values(sequence)
that takes a sequence (even empty) and returns a list of all the values appendable (as a last element) to that sequence. I need to generate all the possible sequences of 4 elements, with respect to the rules defined in this function and starting with an empty sequence.
Example :
Let's say the implementation of get_appendable_values
is :
def get_appendable_values(sequence):
'''Dummy rules'''
if len(sequence) == 2:
return [4, 12]
if sequence[-1] == 4:
return [7]
return [0, 9]
Expected output :
[[0, 0, 4, 7],
[0, 0, 12, 0],
[0, 0, 12, 9],
[0, 9, 4, 7],
[0, 9, 12, 0],
[0, 9, 12, 9],
[9, 0, 4, 7],
[9, 0, 12, 0],
[9, 0, 12, 9],
[9, 9, 4, 7],
[9, 9, 12, 0],
[9, 9, 12, 9]]
I have the feeling that recursion is the key, but I could not figure it out.
CodePudding user response:
Yes, recursion is the key. To generate a sequence of size 4, you first generate all sequences of size 3, and add all possible endings to them. Likewise, to generate a sequence of size 3, you need all sequences of size 2... and so forth down to size 0.
def get_appendable_values(sequence):
'''Dummy rules'''
if len(sequence) == 2:
return [4, 12]
#need a len check here to avoid IndexError when `sequence` is empty
if len(sequence) > 0 and sequence[-1] == 4:
return [7]
return [0, 9]
def generate_sequences(size):
if size == 0:
yield []
else:
for left_part in generate_sequences(size-1):
for right_part in get_appendable_values(left_part):
yield left_part [right_part]
for seq in generate_sequences(4):
print(seq)
Result:
[0, 0, 4, 7]
[0, 0, 12, 0]
[0, 0, 12, 9]
[0, 9, 4, 7]
[0, 9, 12, 0]
[0, 9, 12, 9]
[9, 0, 4, 7]
[9, 0, 12, 0]
[9, 0, 12, 9]
[9, 9, 4, 7]
[9, 9, 12, 0]
[9, 9, 12, 9]
CodePudding user response:
I'm not sure if I understand your problem correctly. Do you want to get a list of the possible permutations of length 4, drawn from the sequence?
In that case, the itertools package might come in handy (see How do I generate all permutations of a list?):
import itertools
a = [2, 4, 6, 8, 10]
permutations_object = itertools.permutations(a, 4)
print(list( permutations_object ))
This outputs a list of tuples which are the permutations:
[(2, 4, 6, 8), (2, 4, 6, 10), (2, 4, 8, 6), (2, 4, 8, 10), ...]
CodePudding user response:
Here's a solution which works using recursion, although as Adrian Usler suggests, using the itertools library probably works better. I think the following code works:
def gen_all_sequences(sequence):
# Recursive base case:
if len(sequence) <= 1:
return [sequence] # Only one possible sequence of length 1
# Recursive general case:
all_sequences = []
for i, elem in enumerate(sequence):
# Construct and append all possible sequences beginning with elem
remaining_elements = sequence[:i] sequence[i 1:]
all_sequences = [[elem] seq for seq in gen_all_sequences(remaining_elements )]
return all_sequences
print(gen_all_sequences(["a","b","c","d"]))
# Will return all arrangements (permutations) of "a", "b", "c" and "d", e.g. abcd, abdc, acbd, acdb etc.