écriture pythonesque

Le
Olivier Ravard
Bonjour à tous,

Voici un petit problème :

J'ai une liste de la forme :
a = [[(1,11),(2,22),(3,33)], [(4,44),(5,55)], ]

et je veux obtenir la liste suivante :
[(1,11),(2,22),(3,33),(4,44),(5,55), ]

Bien sûr, les entiers 1,2,3, , 11, 22, 33,
sont des nombres choisis ici arbitrairement.
Je souhaite faire cette opération de manière "pythonesque"
et efficace (les listes peuvent être longues).

Pour faire cette opération :

1. utilisation de "extend"
b = []
[b.extend(r) for r in a]
il me semble que l'utilisation de "extend" est relativement lente.

2. Utilisation de numpy
c = numpy.ravel(a)
b = [(c[i],c[i+1]) for i in range(len(c))[::2]]
Je ne suis pas sûr que cette solution soit plus rapide que la précédente.
De plus la fonction ravel ne fonctionne que si le nombre d'éléments
de chaque liste de niveau 1 soit de même taille. Dans mon exemple, ça ne
fonctionne que si a = [[(1,11),(2,22),(3,33)], [(4,44),(5,55),(6,66)], ]

Avez-vous d'autres suggestions ?


O.R.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Ravard
Le #18627201
resultat = [r for b in a for r in b]
Bruno Desthuilliers
Le #18628591
Olivier Ravard a écrit :
resultat = [r for b in a for r in b]



Hors contexte, c'est totalement incompréhensible - et donc fort peu
pythonesque.
Olivier Ravard
Le #18629391
Bruno Desthuilliers a écrit :
Olivier Ravard a écrit :
resultat = [r for b in a for r in b]



Hors contexte, c'est totalement incompréhensible - et donc fort peu
pythonesque.



a = [[(1,11),(2,22),(3,33)], [(4,44),(5,55)]]
resultat = [r for b in a for r in b]
print resultat

--> [(1, 11), (2, 22), (3, 33), (4, 44), (5, 55)]

C'est mieux ?
Alain Ketterlin
Le #18629571
Olivier Ravard
Voici un petit problème :

J'ai une liste de la forme :
a = [[(1,11),(2,22),(3,33)], [(4,44),(5,55)], ...]

et je veux obtenir la liste suivante :
[(1,11),(2,22),(3,33),(4,44),(5,55), ...]



reduce(lambda x,y : x+y, a)

-- Alain.
Boris Borcic
Le #18635351
Olivier Ravard wrote:

1. utilisation de "extend"


...
il me semble que l'utilisation de "extend" est relativement lente.



Sur quelle base ?


2. Utilisation de numpy


...
Je ne suis pas sûr que cette solution soit plus rapide que la précé dente.


...
Avez-vous d'autres suggestions ?



Sur le principe de ne pas s'occuper de la performance à moins de la mes urer :

http://docs.python.org/library/timeit.html

Sur le problème de base, vérifier qu'une liste est bien nécessaire, ou si
itertools.chain (<2.6) ou itertools.chain.from_iterable (2.6) peut faire l'affaire.

http://docs.python.org/library/itertools.html#itertools.itertools.chain.f rom_iterable

hth, bb
Michel Claveau - NoSpam SVP ; merci
Le #18636671
Bonsoir !

Tu te définis une petite fonction qui aplatit des listes imbriquées
(quelque soit la profondeur d'imbrication), puis tu l'utilises au
besoin.

Exemple :

def aplati(l):
for item in l:
if isinstance( item, types.ListType):
for iii in aplati( item):
yield iii
else:
yield item

print list(aplati(l))


@+
--
Michel Claveau
Christophe
Le #18641101
Michel Claveau - NoSpam SVP ; merci a écrit :
Bonsoir !

Tu te définis une petite fonction qui aplatit des listes imbriquées
(quelque soit la profondeur d'imbrication), puis tu l'utilises au besoin.

Exemple :

def aplati(l):
for item in l:
if isinstance( item, types.ListType):
for iii in aplati( item):
yield iii
else:
yield item

print list(aplati(l))


@+



Tiens, c'est utile d'utiliser types.ListType au lieu de list ? Moi
j'aurais mis isinstance( item, list ). Y aurait-il un problème avec
cette notation ?
Olivier Ravard
Le #18641351
Boris Borcic wrote:
Olivier Ravard wrote:

1. utilisation de "extend"


...
il me semble que l'utilisation de "extend" est relativement lente.



Sur quelle base ?



Il est vrai que ce n'est qu'une impression conditionnée par une réflexion qui n'est pas
objective. Cette impression est le résultat de mon expérience où, dans certains cas
(réception TCP d'un flux haut débit - de l'ordre de 800 Mb/s par exemple), la création de
chaines puis l'utilisation de "join" est beaucoup plus rapide que l'utilisation de
"append". Ceci dit, ce sont des chaînes et non des listes.
Je n'ai pas fait de mesures de vitesse.


2. Utilisation de numpy


...
Je ne suis pas sûr que cette solution soit plus rapide que la précédente.


...
Avez-vous d'autres suggestions ?



Sur le principe de ne pas s'occuper de la performance à moins de la
mesurer :

http://docs.python.org/library/timeit.html

Sur le problème de base, vérifier qu'une liste est bien nécessaire, ou
si itertools.chain (<2.6) ou itertools.chain.from_iterable (2.6) peut
faire l'affaire.

http://docs.python.org/library/itertools.html#itertools.itertools.chain.from_iterable


hth, bb



Michel Claveau - NoSpam SVP ; merci
Le #18641961
Bonjour !

J'ai pris l'habitude d'utiliser types car ce module contient des types
génériques très pratiques. Comme, par exemple, types.StringTypes, qui
permet de tester à la fois les chaînes String et Unicode.
Du coup, j'utilise toujours la même notation, ce qui m'évite de me poser
des questions.

@+
--
Michel Claveau
Michel Claveau - NoSpam SVP ; merci
Le #18642191
Bonjour !

reduce(



reduce est excellent, pour ce genre de chose (tant qu'il n'y a pas
plusieurs niveaux, et donc pas de récursion). Attention, avec Python 3,
cette fonction va migrer dans functools.

@+
--
Michel Claveau
Publicité
Poster une réponse
Anonyme