I have three lists:
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
What I hope to get is a list like the following:
list_04 = ['DOG','V','A','CAT','W','B','BEAR','X','C','Y','D','Z','E','F','G','H']
This list is supposed to contain one item from list 1, then one from list 2, and one from list 3. This then continues until list 1 is exhausted; list 1 should then be ignored, and the same process should happen on just lists 2 and 3, continuing until all lists are empty.
Edit: this answers merges the lists in an unordered fashion, which is not exactly what OP wanted.
Use itertools.chain to chain the lists together into a single list, and then random.shuffle to shuffle this list in-place:
from itertools import chain
from random import shuffle
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
full_list = list(chain(list_01, list_02, list_03))
shuffle(full_list)
print(full_list) # in my case: ['BEAR', 'V', 'Z', 'W', 'A', 'Y', 'E', 'G', 'CAT', 'B', 'X', 'H', 'D', 'F', 'DOG', 'C']
It seems like you want to do this in order, not randomly. If so, you can use zip_longest() from itertools and make a nested list comprehension:
from itertools import zip_longest
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
list_04 = [n for group in zip_longest(list_01, list_02, list_03)
for n in group if n is not None]
# ['DOG', 'V', 'A', 'CAT', 'W', 'B', 'BEAR', 'X', 'C', 'Y', 'D', 'Z', 'E', 'F', 'G', 'H']
Note: zip_longest will produce None values when one list runs out. That's why we are filtering for None in the comprehension.
You can use zip function
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
minimum_size = min(len(list_01) , len(list_02) , len(list_03))
new_array = []
for item1 , item2 , item3 in zip(list_01 , list_02 , list_03):
new_array.extend([item1 , item2 , item3])
new_array += list_01[minimum_size:] + list_02[minimum_size:] + list_03[minimum_size:]
print(new_array)
You can use zip_longest and chain from the itertools module:
from itertools import chain, zip_longest
list_04 = [i for i in chain(*zip_longest(list_01, list_02, list_03))
if i is not None]
output:
['DOG', 'V', 'A', 'CAT', 'W', 'B', 'BEAR', 'X', 'C', 'Y', 'D', 'Z', 'E', 'F', 'G', 'H']
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
L = [list_01, list_02, list_03]
def shuffle(L):
result = []
while any(L):
for sub in L:
if sub:
result.append(sub.pop(0))
return result
print(shuffle(L))
Output:
['DOG', 'V', 'A', 'CAT', 'W', 'B', 'BEAR', 'X', 'C', 'Y', 'D', 'Z', 'E', 'F', 'G', 'H']
By using plain python(without numpy), this is the best I could come up with.
I believe it works for any order, length of lists and does not assume fill_value
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
L = [list_01, list_03, list_02]
def zigzag(*arg):
i = 0
LL = []
all_done = False
while not all_done:
all_done = True
for l in arg:
if i >= len(l):
continue
all_done = False
LL.append(l[i])
i += 1
return LL
print(zigzag(list_01, list_02, list_03))
print(zigzag(list_01, list_03, list_02))
The easiest way:
result = list(roundrobin(list_01, list_02, list_03))
Just copy&paste roundrobin from the Itertools Recipes or import it from more-itertools (as mentioned by the recipes section).
Alternatively, I like using heapq.merge:
result = list(map(itemgetter(1), merge(*map(enumerate, lists), key=itemgetter(0))))
Variant:
index, value = map(itemgetter, (0, 1))
result = list(map(value, merge(*map(enumerate, lists), key=index)))
Full code (Try it online!):
from operator import itemgetter
from heapq import merge
list_01 = ['DOG','CAT','BEAR']
list_02 = ['V','W','X','Y','Z']
list_03 = ['A','B','C','D','E','F','G','H']
lists = list_01, list_02, list_03
expect = ['DOG','V','A','CAT','W','B','BEAR','X','C','Y','D','Z','E','F','G','H']
result = list(map(itemgetter(1), merge(*map(enumerate, lists), key=itemgetter(0))))
print(result == expect)
index, value = map(itemgetter, (0, 1))
result = list(map(value, merge(*map(enumerate, lists), key=index)))
print(result == expect)
You can use more_itertools.interleave_longest:
>>> from more_itertools import interleave_longest
>>> list(interleave_longest(
... ['DOG','CAT','BEAR'],
... ['V','W','X','Y','Z'],
... ['A','B','C','D','E','F','G','H'],
... ))
['DOG', 'V', 'A', 'CAT', 'W', 'B', 'BEAR', 'X', 'C', 'Y', 'D', 'Z', 'E', 'F', 'G', 'H']