Reputation: 277
I would like to merge two input lists together and get all permutations of their elements such that the ordering of the elements in each input list is retained.
For example, if I have two lists: ['b','a']
and ['c','d']
, I would like to get the following lists:
['b', 'a', 'c', 'd'],
['b', 'c', 'a', 'd'],
['b', 'c', 'd', 'a'],
['c', 'b', 'a', 'd'],
['c', 'b', 'd', 'a'],
['c', 'd', 'b', 'a']
where the order of the elements from the original lists is retained (b comes before a, c comes before d).
I have found a post dealing with a similar problem but using strings as inputs instead of lists: Restricted Permutations of Strings in Python. For example, with the strings "ba" and "cd" as inputs, strings "bacd", "bcad", "bcda", "cbad", "cbda", "cdba" will be returned.
I have tried to adapt the code there to my problem, but it didn't work. Using the same example as above, I got [None, None, None, None, None, None] instead of the 6 lists that I expected. Below is the code I used.
def ordered_permutations(list1, list2):
perms = []
if len(list1) + len(list2) == 1:
return [list1 or list2]
if list1:
for item in ordered_permutations(list1[1:], list2):
perms.append([list1[0]].append(item))
if list2:
for item in ordered_permutations(list1, list2[1:]):
perms.append([list2[0]].append(item))
return perms
Upvotes: 1
Views: 880
Reputation: 1121834
list.append()
returns None
as the list is altered in-place. You should use concatenation instead:
def ordered_permutations(list1, list2):
perms = []
if len(list1) + len(list2) == 1:
return [list1 or list2]
if list1:
for item in ordered_permutations(list1[1:], list2):
perms.append([list1[0]] + item)
if list2:
for item in ordered_permutations(list1, list2[1:]):
perms.append([list2[0]] + item)
return perms
This then produces your required output:
>>> def ordered_permutations(list1, list2):
... perms = []
... if len(list1) + len(list2) == 1:
... return [list1 or list2]
... if list1:
... for item in ordered_permutations(list1[1:], list2):
... perms.append([list1[0]] + item)
... if list2:
... for item in ordered_permutations(list1, list2[1:]):
... perms.append([list2[0]] + item)
... return perms
...
>>> for combo in ordered_permutations(['b','a'], ['c', 'd']):
... print combo
...
['b', 'a', 'c', 'd']
['b', 'c', 'a', 'd']
['b', 'c', 'd', 'a']
['c', 'b', 'a', 'd']
['c', 'b', 'd', 'a']
['c', 'd', 'b', 'a']
Upvotes: 2