Tengo tres listas:
list_01 = ['DOG','CAT','BEAR'] list_02 = ['V','W','X','Y','Z'] list_03 = ['A','B','C','D','E','F','G','H']Lo que espero obtener es una lista como la siguiente:
list_04 = ['DOG','V','A','CAT','W','B','BEAR','X','C','Y','D','Z','E','F','G','H']Se supone que esta lista contiene un elemento de la lista 1, luego uno de la lista 2 y uno de la lista 3. Esto continúa hasta que se agota la lista 1; la lista 1 debe ignorarse y el mismo proceso debe ocurrir solo en las listas 2 y 3, continuando hasta que todas las listas estén vacías.
Editar: esta respuesta fusiona las listas de forma desordenada, que no es exactamente lo que OP quería.
Use itertools.chain para encadenar las listas en una sola lista y luego random.shuffle para mezclar esta lista en el lugar:
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']Parece que quieres hacer esto en orden, no al azar. Si es así, puede usar zip_longest() de itertools y hacer una comprensión de lista anidada:
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'] Nota: zip_longest producirá valores None cuando se agote una lista. Es por eso que estamos filtrando por None en la comprensión.
Puedes usar la función zip
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)Puede usar zip_longest y chain desde el módulo itertools :
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]producción:
['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))Producción:
['DOG', 'V', 'A', 'CAT', 'W', 'B', 'BEAR', 'X', 'C', 'Y', 'D', 'Z', 'E', 'F', 'G', 'H']Al usar python simple (sin numpy), esto es lo mejor que se me ocurrió.
Creo que funciona para cualquier orden, longitud de listas y no asume 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))La forma más fácil:
result = list(roundrobin(list_01, list_02, list_03)) Simplemente copie y pegue roundrobin desde las recetas de Itertools o impórtelo desde more-itertools (como se menciona en la sección de recetas).
Alternativamente, me gusta usar heapq.merge :
result = list(map(itemgetter(1), merge(*map(enumerate, lists), key=itemgetter(0))))Variante:
index, value = map(itemgetter, (0, 1)) result = list(map(value, merge(*map(enumerate, lists), key=index)))Código completo ( ¡Pruébelo en línea! ):
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)Puedes usar 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']