2013-03-14 14 views

risposta

60
tup = tuple((element.foo, element.bar) for element in alist) 

Tecnicamente, si tratta di un generator expression. È come una lista di comprensione, ma è valutato pigramente e non avrà bisogno di allocare memoria per una lista intermedia.

Per completezza, la lista di comprensione sarebbe simile a questa:

tup = tuple([(element.foo, element.bar) for element in alist]) 

 

PS: attrgetter non è più veloce (alist ha un milione di articoli qui):

In [37]: %timeit tuple([(element.foo, element.bar) for element in alist]) 
1 loops, best of 3: 165 ms per loop 

In [38]: %timeit tuple((element.foo, element.bar) for element in alist) 
10 loops, best of 3: 155 ms per loop 

In [39]: %timeit tuple(map(operator.attrgetter('foo','bar'), alist)) 
1 loops, best of 3: 283 ms per loop 

In [40]: getter = operator.attrgetter('foo','bar') 

In [41]: %timeit tuple(map(getter, alist)) 
1 loops, best of 3: 284 ms per loop 

In [46]: %timeit tuple(imap(getter, alist)) 
1 loops, best of 3: 264 ms per loop 
+0

(+ 1) Potrebbe valere la pena sottolineare che tecnicamente, questa non è una lista di comprensione (ma sono sicuro che l'OP non mi dispiacerebbe :)) – NPE

+2

d anche fare 'tupla (map (operator.attrgetter ('foo', 'bar'), alist))'. Probabilmente userò quello che hai postato per la leggibilità, ma 'attrgetter' potrebbe avere un leggero vantaggio in termini di prestazioni. Dovresti "timeit" e vedere se questo è in un vero e proprio anello di tensione. – mgilson

+1

Qual è la differenza tra una comprensione di lista e un'espressione di generatore in questo esempio dato che su di essa viene chiamata tuple()? Non consumerebbe la stessa impronta di memoria indipendentemente dal modulo? – Octipi

Problemi correlati