# Unique combinations of all elements from long python list with elements from shorter list

## Issue

I have two lists:

``````trips = ['trip1', 'trip2', 'trip3', 'trip4',...., 'tripN']

trucks = ['A', 'B', 'C']
``````

I want to obtain all possible unique combinations so that all trips are matched with a truck in the trucks list. Please note, that all trucks must execute the same number of trips. In the above case for example if `len(trips) == 12` then all trucks must be matched with 4 trips each.

Moreover,

``````extra_trips = len(trips) % len(trucks). If extra_trips != 0
``````

then get also all the unique combinations of trips-trucks by matching the remaining trip with whatever truck.
I have done the following but I have trouble to proceed:

``````import itertools
import random
trucks=['A','B','C']
trips = ['trip1', 'trip2', 'trip3', 'trip4']

combs= [list(itertools.zip_longest(trucks, x)) for x in itertools.permutations(trips,len(trips))]
``````

From the above code, I get this output:

``````[[('A', 'trip1'), ('B', 'trip2'), ('C', 'trip3'), (None, 'trip4')], [('A', 'trip1'), ('B', 'trip2'), ('C', 'trip4'), (None, 'trip3')], [('A', 'trip1'), ('B', 'trip3'), ('C', 'trip2'), (None, 'trip4')], [('A', 'trip1'), ('B', 'trip3'), ('C', 'trip4'), (None, 'trip2')], [('A', 'trip1'), ('B', 'trip4'), ('C', 'trip2'), (None, 'trip3')], [('A', 'trip1'), ('B', 'trip4'), ('C', 'trip3'), (None, 'trip2')], [('A', 'trip2'), ('B', 'trip1'), ('C', 'trip3'), (None, 'trip4')], [('A', 'trip2'), ('B', 'trip1'), ('C', 'trip4'), (None, 'trip3')], [('A', 'trip2'), ('B', 'trip3'), ('C', 'trip1'), (None, 'trip4')], [('A', 'trip2'), ('B', 'trip3'), ('C', 'trip4'), (None, 'trip1')], [('A', 'trip2'), ('B', 'trip4'), ('C', 'trip1'), (None, 'trip3')], [('A', 'trip2'), ('B', 'trip4'), ('C', 'trip3'), (None, 'trip1')], [('A', 'trip3'), ('B', 'trip1'), ('C', 'trip2'), (None, 'trip4')], [('A', 'trip3'), ('B', 'trip1'), ('C', 'trip4'), (None, 'trip2')], [('A', 'trip3'), ('B', 'trip2'), ('C', 'trip1'), (None, 'trip4')], [('A', 'trip3'), ('B', 'trip2'), ('C', 'trip4'), (None, 'trip1')], [('A', 'trip3'), ('B', 'trip4'), ('C', 'trip1'), (None, 'trip2')], [('A', 'trip3'), ('B', 'trip4'), ('C', 'trip2'), (None, 'trip1')], [('A', 'trip4'), ('B', 'trip1'), ('C', 'trip2'), (None, 'trip3')], [('A', 'trip4'), ('B', 'trip1'), ('C', 'trip3'), (None, 'trip2')], [('A', 'trip4'), ('B', 'trip2'), ('C', 'trip1'), (None, 'trip3')], [('A', 'trip4'), ('B', 'trip2'), ('C', 'trip3'), (None, 'trip1')], [('A', 'trip4'), ('B', 'trip3'), ('C', 'trip1'), (None, 'trip2')], [('A', 'trip4'), ('B', 'trip3'), ('C', 'trip2'), (None, 'trip1')]]
``````

As you can see, it returns some combinations but for every comb, one trip is not matched.

## Solution

Using `zip_longest` sort of sounds like the right approach, but you need to `cycle` the shorter list so that if they don’t share a common divisor some trucks will get repeated.

``````from itertools import cycle

def zip_cycle_shorter(a, b):
if len(a) < len(b):
a = cycle(a)
elif len(b) < len(a):
b = cycle(b)
return zip(a, b)

list(zip_cycle_shorter([1,2,3], ['a','b','c','d','e']))
``````

gives me: `[(1, 'a'), (2, 'b'), (3, 'c'), (1, 'd'), (2, 'e')]`

which is what I think you want. It might be instructive to try generalising this to support an arbitrary number of lists. For example, try filling in code to complete:

``````def zip_cycle_shorter(*lists):
...
``````

(you just use comprehensions instead of handling each case specifically)