I want to zip two list with different length
A = [1,2,3,4,5,6,7,8,9] B = ["A","B","C"]
and I expect this
[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'A'), (5, 'B'), (6, 'C'), (7, 'A'), (8, 'B'), (9, 'C')]
But the build-in
zip won’t repeat to pair with the list with larger size .
Does there exist any build-in way can achieve this?
here is my code
idx = 0 zip_list =  for value in larger: zip_list.append((value,smaller[idx])) idx += 1 if idx == len(smaller): idx = 0
You can use
Make an iterator returning elements from the iterable and saving a copy of each. When the iterable is exhausted, return elements from the saved copy. Repeats indefinitely.
A = [1,2,3,4,5,6,7,8,9] B = ["A","B","C"] from itertools import cycle zip_list = zip(A, cycle(B)) if len(A) > len(B) else zip(cycle(A), B)
A = [1,2,3,4,5,6,7,8,9] B = ["A","B","C"] Z =  for i, a in enumerate(A): Z.append((a, B[i % len(B)]))
Just make sure that the larger list is in
You can use
from itertools import cycle my_list = [1, 2, 3, 5, 5, 9] another_list = ['Yes', 'No'] cyc = cycle(another_list) print([[i, next(cyc)] for i in my_list]) # [[1, 'Yes'], [2, 'No'], [3, 'Yes'], [5, 'No'], [5, 'Yes'], [9, 'No']]
Do you know that the second list is shorter?
import itertools list(zip(my_list, itertools.cycle(another_list)))
This will actually give you a list of tuples rather than a list of lists. I hope that’s okay.
Solution for an arbitrary number of iterables, and you don’t know which one is longest (also allowing a default for any empty iterables):
from itertools import cycle, zip_longest def zip_cycle(*iterables, empty_default=None): cycles = [cycle(i) for i in iterables] for _ in zip_longest(*iterables): yield tuple(next(i, empty_default) for i in cycles) for i in zip_cycle(range(2), range(5), ['a', 'b', 'c'], ): print(i)
(0, 0, 'a', None) (1, 1, 'b', None) (0, 2, 'c', None) (1, 3, 'a', None) (0, 4, 'b', None)
You can use the modulo
% operator in a loop that counts up
my_list=[1, 2, 3, 5, 5, 9] another_list=['Yes','No'] new_list =  for cur in range(len(my_list)): new_list.append([my_list[cur], another_list[cur % 2]]) # [[1, 'Yes'], [2, 'No'], [3, 'Yes'], [5, 'No'], [5, 'Yes'], [9, 'No']]
2 can be replaced with
A very simple approach is to multiply the short list so it’s longer:
my_list = [1, 2, 3, 5, 5, 9] another_list = ['Yes', 'No'] zip(my_list, another_list*3)) #[(1, 'Yes'), (2, 'No'), (3, 'Yes'), (5, 'No'), (5, 'Yes'), (9, 'No')]
Note here that the multiplier doesn’t need to be carefully calculated since
zip only goes out to the length of the shortest list (and the point of the multiplier is to make sure the shortest list is
my_list). That is, the result would be the same if
100 were used instead of
symmetric, no conditionals one liner
[*zip(A*(len(B)//len(A) + 1), B*(len(A)//len(B) + 1))]
which strictly answers ‘How to zip two differently sized lists?’
needs a patch for equal sized lists to be general:
[*(zip(A, B) if len(A) == len(B) else zip(A*(len(B)//len(A) + 1), B*(len(A)//len(B) + 1)))]