Bonjour,
Comment utiliser map(f,...) lorsqu'un des arguments de f() est constant (i.e ne dépend pas de l'itérable) ?
Pour l'instant je multiplie une liste avec l'argument constant. A priori peu efficace (un appel à len() et la multiplication de la liste).
Voici un exemple (voir fonction f5() ), ou j'essaye d'optimiser le problème suivant: créer la liste l_x des o.x depuis une liste l d'objets o ayant un champ x.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 def get_x(r): return r.x import random class obj: def __init__(self): self.x= random.random() def f(self): return self.x o= obj() l= [o]*1000 def f1(): l_x=[] for k in l: l_x.append(k.x) def f2(): l_x=[k.x for k in l] def f3(): l_x= map(get_x,l) def f4(): l_x= map(obj.f,l) "Exemple de map avec argument constant" def f5(): l_constantArg= ["x"]*len(l) l_x= map(getattr,l,l_constantArg) def run(fun,repet,name,*args,**kargs): """ appel fun(*args,**kwargs) repet. fois. Mesure et affiche le temps """ R= xrange(repet) t= time.clock() for m in R: res= fun(*args,**kargs) dt= time.clock() - t print "fun %s has run.%s in %s " %(name,repet,dt) run(f1,100,'for k in :',l) run(f2,100,'[list_comp]',l) run(f3,100,'map global get_x()',l) run(f4,100,'map class.get()',l) run(f5,100,'map getattr',l)
Resultats (debug mode san psyko):
fun for k in : has run.100 in 0.0350195346057
fun [list_comp] has run.100 in 0.0227143393923
fun map global get_x() has run.100 in 0.798853485569
fun map class.get() has run.100 in 0.848990583999
fun map getattr has run.100 in 0.0160827702962
NB: Le gain dépend fortement de la longueur de la liste l. Il n'a pas l'air monotone.
Resultats (avec psyko):
fun for k in : has run.100 in 0.019553602483
fun [list_comp] has run.100 in 0.00934755674255
fun map global get_x() has run.100 in 0.0231512664319
fun map class.get() has run.100 in 0.0810935468055
fun map getattr has run.100 in 0.0158168147069
La question est puis-je faire mieux que f5() ?
Par exemple comment puis-je appeler la built-in getattr avec un tuple d'argument (je pense à map(gettattr, zip(l,["x"]) ), qui ne marche pas tel quel.
Mes essais avec zip ou iterttools.starmap() ou .imap() m'ont fortement decu.
Dit autrement, comment combine-t'on les fonctions built-in intelligemment pour obtenir une classe de fonctions assez large ?
Merci d'avance
Partager