2013-03-14 51 views

回答

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

从技术上讲,这是一个generator expression。它就像一个列表理解,但它是懒惰评估的,不需要为中间列表分配内存。

为了完整起见,列表理解是这样的:

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

 

PS:attrgetter是不是更快(alist在这里有一万件):

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)值得指出的是,从技术上讲,这不是一个列表理解(但我相信OP不会介意:)) – NPE 2013-03-14 13:07:43

+2

you coul d也做'tuple(map(operator.attrgetter('foo','bar'),alist))'。我可能会使用您发布的内容来提高可读性,但“attrgetter”可能会略有性能优势。你不得不“时间”,看看这是否是一个真正的紧密循环。 – mgilson 2013-03-14 13:11:44

+1

这个例子中的列表理解和生成器表达式有什么区别,因为它调用了tuple()?不管形式如何,它都不会消耗相同的内存空间? – Octipi 2013-03-14 13:14:12