Search code examples
pythonpython-itertools

Permutations between 2 lists


From 2 list i would like to know an optimal way in Python to do a sort of "indexed permutation". This is how this would look like :

input :

list2 = [3,4,5]
list1 = [0,1,2]

output

[[0,1,2], [0,1,5], [0,4,2], [3,1,2],
      [3,4,5], [3,4,2], [3,1,5], [0,4,5],
]

So each element of the lists remains in the same index.


Solution

  • You basically want two variables: list_to_pick, which can vary in range(number_of_lists), and index_to_swap which can vary in the range(-1, len(list1)). Then, you want the product of these two ranges to decide which list to pick, and which item to swap. When index_to_swap is -1, we won't swap any items

    import itertools
    
    source = [list1, list2]
    
    result = []
    
    for list_to_pick, index_to_swap in itertools.product(range(len(source)), range(-1, len(source[0])):
        # Make a copy so we don't mess up the original list
        selected_list = source[list_to_pick].copy() 
    
        # There are only two lists, so the other list is at index abs(list_to_pick - 1)
        other_list = source[abs(list_to_pick - 1)]
    
        # We swap only if index_to_swap >= 0
        if index_to_swap >= 0:
            selected_list[index_to_swap] = other_list[index_to_swap] 
    
        result.append(selected_list)
    

    Which gives:

    [[0, 1, 2],
     [3, 1, 2],
     [0, 4, 2],
     [0, 1, 5],
     [3, 4, 5],
     [0, 4, 5],
     [3, 1, 5],
     [3, 4, 2]]
    

    The order is not the same as your required list, but all the "permutations" are there. If you want the same order as in your question, you will have to define the second argument to itertools.product as:

    swap_indices = [-1] + list(range(len(source[0])-1, -2, -1))