3
votes

Insérer des éléments d'une liste dans une autre liste toutes les n positions

J'ai la liste suivante.

output = [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]

Je veux obtenir ce qui suit en insérant tous les deux éléments.

vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]

Pas seulement le La liste Python, mais aussi la réponse en utilisant le tableau numpy est très bien.


0 commentaires

5 Réponses :


1
votes

Je ne pense pas qu'il y ait un moyen facile de faire cela pour NumPy pour n'importe quelle taille possible de tableaux, mais voici une façon python de le faire en utilisant des itérateurs et une compréhension de liste:

it1, it2 = map(iter, (vector, inserted_elements))
n = sum(map(len, (vector, inserted_elements)))

[next(it2) if i % 3 == 0 else next(it1) for i in range(1, n+1)]
# [1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]

Tous les 3 L'élément rd dans la sortie proviendra de it2 , l'itérateur pour insert_elements . Le reste provient de it1 qui correspond à vector.


0 commentaires

1
votes

étape du tableau numpy:

1.

>>> result=np.array(M).flatten()
>>> result
array([ 1,  2,  2,  3,  4,  2,  5,  6,  2,  7,  8,  2,  9, 10,  2])

2.

>>> M = np.append(a, b, axis=1)
>>> M
matrix([[ 1,  2,  2],
        [ 3,  4,  2],
        [ 5,  6,  2],
        [ 7,  8,  2],
        [ 9, 10,  2]])

3.

>>> b=np.reshape(np.matrix([2, 2, 2, 2, 2]),(5, 1))
>>> b
matrix([[2],
        [2],
        [2],
        [2],
        [2]])

4.

>>> a=np.reshape(np.matrix([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),(5, 2))
>>> a
matrix([[ 1,  2],
        [ 3,  4],
        [ 5,  6],
        [ 7,  8],
        [ 9, 10]])


0 commentaires

1
votes

Une approche traditionnelle de la boucle for pourrait ressembler à ce qui suit, où vous choisissez 2 éléments dans vector et 1 élément dans insert_elements et effectuez la sortie code> list

[1, 2, 2, 3, 4, 2, 5, 6, 2, 7, 8, 2, 9, 10, 2]

La même chose dans la compréhension de liste sera

output = [ v for idx in range(0,len(vector),2) for v in vector[idx:idx+2] + [inserted_elements[int(idx/2)]]]

La sortie sera

vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2, 2]

output = []

#Pick two elements from vector and one element from inserted_elements and add it to output list
for idx in range(0,len(vector),2):

    output.extend(vector[idx:idx+2] + [inserted_elements[int(idx/2)]])

print(output)


0 commentaires

1
votes

Voici une approche quelque peu obscure - mais c'est plus rapide que toute autre chose (jusqu'à présent):

In [254]: list(zip(*[iter(vector)]*2+[iter(inserted_elements)]))                                         
Out[254]: [(1, 2, 2), (3, 4, 2), (5, 6, 2), (7, 8, 2), (9, 10, 2)]

Il utilise un 'idiome' pour prendre des éléments de taille n groupes, [iter (alist)] * n et itertools.chain comme moyen d'aplatir une liste imbriquée.

Une réponse supprimée utilisait np.insert code>. Pour cela, je crois que insert utilise le masquage comme indiqué ci-dessous:

np.column_stack((np.reshape(vector,(-1,2)), inserted_elements)).ravel()

Une variante de la réponse np.append est:

def foo(vector, inserted_elements):
    res = np.zeros(len(vector)+len(inserted_elements),int)  
    mask = res.astype(bool) 
    mask[2::3]=True 
    res[mask]=inserted_elements 
    res[~mask]=vector    
    return res

Je n'aime généralement pas np.append , car il est souvent mal utilisé, en particulier dans les boucles. Pour cela, ça va, mais je pense que column_stack est plus propre.

===

list(itertools.chain(*zip(*[iter(vector)]*2+[iter(inserted_elements)]))) 


1 commentaires

foo était ce que j'ai implémenté, seulement pour voir que vous l'avez déjà fait lol.



1
votes

Voici une approche basée sur itertools , qui fonctionne également pour un nombre arbitraire d'éléments à insérer d'une liste à l'autre. Pour cela, j'ai défini une fonction de générateur, qui insérera un élément de l2 dans l1 tous les éléments i :

vector = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
inserted_elements = [2, 2, 2, 2]

list(insert_every_n(vector, inserted_elements, k=3))
# [1, 2, 3, 2, 4, 5, 6, 2, 7, 8, 9, 2, 10, 2]


0 commentaires