5
votes

Combinez des éléments de deux listes

Je veux fusionner deux tableaux en python d'une manière spéciale. Les entrées avec un index impair de mon tableau de sortie out seront les entrées correspondantes de mon premier tableau d'entrée in0 . Les entrées avec un index pair dans out seront les entrées correspondantes de mon deuxième tableau d'entrée in1.

in0 , in1 et out ont tous la même longueur.

Exemple:

Les tableaux d'entrée

out = [0, 5, 2, 7]

doivent être fusionnés avec le tableau de sortie

in0 = [0, 1, 2, 3]
in1 = [4, 5, 6, 7]

Y a-t-il un moyen plus agréable que de boucler sur toute la longueur des entrées et de remplir mon out 'à la main'?


0 commentaires

4 Réponses :


11
votes

Vous pouvez utiliser une compréhension de liste et sélectionner des valeurs de in0 sur les indices pairs et in1 sur les indices impairs:

[in0[i] if i % 2 == 0 else in1[i] for i in range(len(in0))]
# [0, 5, 2, 7]


6 commentaires

Je ne comprends pas toute la syntaxe mais je vais la chercher. Je vous remercie!


i% 2 == 0 vérifie si le reste de l'action i / 2 est 0 . S'il est 0 l'index est pair et un élément de in0 sera ajouté, sinon de id1 . YW :-)


La même idée pourrait être écrite de manière plus concise sous la forme [x [i% 2] pour i, x dans enumerate (zip (in0, in1))] .


les crochets externes et le for i dans range () m'ont dérouté car je ne suis pas très familier avec python. Mais je l'ai recherché et la compréhension de la liste est une fonctionnalité intéressante de python que je ne connaissais pas


Oui gentil @chepner


Cela simplifie également ma propre réponse.



2
votes

Sans utiliser de boucles, mais pas exactement dans le même ordre que vous avez demandé:

>> import itertools
>> in0 = [0, 1, 2, 3]
>> in1 = [4, 5, 6, 7]
>> out = list(itertools.chain(*zip(in0[0::2], in1[1::2])))
>> out
[0, 5, 2, 7]

EDIT: correction de l'ordre de sortie avec itertools:

>> in0 = [0, 1, 2, 3]
>> in1 = [4, 5, 6, 7]
>> out = in0[0::2] + in1[1::2]
>> out
[0, 2, 5, 7]


1 commentaires

Cela a l'air sympa mais je veux garder l'ordre



8
votes

Si vous souhaitez copier la liste complète, c'est simple avec le découpage:

>>> in0 = [0, 1, 2, 3]
>>> in1 = [4, 5, 6, 7]
>>> out = in0[:]
>>> out[1::2] = in1[1::2]
>>> out
[0, 5, 2, 7]


2 commentaires

Très agréable. Malheureusement, j'ai trop simplifié mon exemple: mes entrées sont des chaînes et out [1 :: 2] = in1 [1 :: 2] ne fonctionne apparemment pas avec des chaînes. Mais c'est la syntaxe agréable et propre que j'espérais!


Solution très élégante. Devrait être accepté comme réponse!



5
votes

Si un peu de verbosité ne vous dérange pas ...

[(0,4)[0], (1,5)[1], (2,6)[0], (3,7)[1]]

Comment ça marche:

  1. zip (in0, in1) est une séquence de tuples, (0,4), (1,5), (2,6), (3,7 ) .

  2. cycle ([0,1]) est un flux sans fin d'alternance de 0 et de 1 à utiliser comme index dans les tuples de l'étape 1.

  3. zip (zip (...), cycle (...)) produit une paire de tuples et d'indices:

    (0, (0,4)), (1, (1,5)), (0, (2,6)), (1, (3,7)).
    
  4. La compréhension de la liste prend l'élément correct de chaque tuple.

Au final, la compréhension de liste est une version générale de

from itertools import cycle

in0 = [0, 1, 2, 3]
in1 = [4, 5, 6, 7]

out = [pair[i] for pair, i in zip(zip(in0, in1), cycle([0,1]))]


0 commentaires