55 votes

Liste avec des valeurs et un suffixe dupliqués

J'ai une liste, a :

a = ['a','b','c']

et j'ai besoin de dupliquer certaines valeurs avec le suffixe _ind ajoutés de cette façon (l'ordre est important) :

['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

J'ai essayé :

b = [[x, x + '_ind'] for x in a]
c = [item for sublist in b for item in sublist]
print (c)
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

Y a-t-il une meilleure solution, plus pythique ?

8 votes

Pour mémoire, il n'y a rien de mal à cette solution.

66voto

MSeifert Points 6307

Tu pourrais en faire un générateur :

def mygen(lst):
    for item in lst:
        yield item
        yield item + '_ind'

>>> a = ['a','b','c']
>>> list(mygen(a))
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

Vous pouvez également le faire avec itertools.product , itertools.starmap ou itertools.chain ou des compréhensions imbriquées, mais dans la plupart des cas, je préfère une fonction de générateur personnalisée, simple à comprendre.


Avec python3.3, vous pouvez également utiliser yield from -pour rendre cette solution élégante un peu plus concise :

def mygen(lst):
    for item in lst:
        yield from (item, item + '_ind')

29voto

Psidom Points 115100

On peut la raccourcir un peu en déplaçant les options vers la boucle for interne dans la compréhension de la liste :

a = ['a','b','c']

[item for x in a for item in (x, x + '_ind')]
# ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

15voto

coldspeed Points 111053

Une autre alternative avec l'épissage (Python2.x, 3.x) :

result = [None] * len(a) * 2
result[::2], result[1::2] = a, map(lambda x: x + '_ind', a)

result
# ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

1 votes

"Python 3.x seulement" - En fait, il s'agit uniquement de Python 3.3 et plus. Voir aquí

0 votes

@ChristianDean Merci. J'ai ajouté le lien.

0 votes

Avez-vous besoin des deux list et les parenthèses (de compréhension de la liste ?) ?

6voto

Ajax1234 Points 42210

Vous pouvez utiliser itertools.chain() :

import itertools

l = ['a','b','c']

new_list = list(itertools.chain.from_iterable([[i, i+"_ind"] for i in l]))

print new_list

Sortie :

['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

4 votes

J'utiliserais chain.from_iterable . De cette façon, vous n'avez pas besoin du déballage avec *

1 votes

Alt : list(itertools.chain(*zip(a, [x + '_ind' for x in a])) ) ou list(itertools.chain(*zip(a, map(lambda x: x + '_ind', a))))

1 votes

D'accord, mais encore une fois, chain.from_iterable serait, à mon avis, un peu plus propre :) list(chain.from_iterable(zip(a, [i+'_ind' for i in a]))) . Non pas que ce soit particulièrement important.

5voto

Leon Points 20011

Avant que les compréhensions et les générateurs de listes ne soient inventés/se répandent, les gens avaient l'habitude de penser de manière beaucoup plus simple 1 :

>>> a = ['a', 'b', 'c']
>>> b = []
>>> for x in a: b.extend([x, x+'_ind'])
... 
>>> b
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

* Je ne veux pas dire que ces constructions/outils sont mauvais, mais je voulais simplement souligner qu'il existe une solution simple.

0 votes

Pour autant que je sache, les compréhensions et les générateurs ont été inventés (mis en œuvre) pour rendre ces "constructions et outils" plus simples (et certainement beaucoup plus rapides). Mais je suppose que c'est une déclaration basée sur une opinion, donc YMMV.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X