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
fonte
2013-03-14 13:06:49
(+ 1) Potrebbe valere la pena sottolineare che tecnicamente, questa non è una lista di comprensione (ma sono sicuro che l'OP non mi dispiacerebbe :)) – NPE
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
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