Python中无 [ ] 的列表理解

2024-04-20 14:26:57 发布

您现在位置:Python中文网/ 问答频道 /正文

加入列表:

>>> ''.join([ str(_) for _ in xrange(10) ])
'0123456789'

join必须接受iterable。

显然,join的参数是[ str(_) for _ in xrange(10) ],它是list comprehension

看看这个:

>>>''.join( str(_) for _ in xrange(10) )
'0123456789'

现在,join的参数只是str(_) for _ in xrange(10),不是[],但是结果是一样的。

为什么?str(_) for _ in xrange(10)是否也生成列表或iterable?


Tags: in列表for参数iterablelistjoinstr
3条回答

第二个示例使用生成器表达式,而不是列表理解。不同的是,使用列表理解,列表完全被构建并传递给.join()。使用生成器表达式,项将逐个生成并由.join()使用。后者使用更少的内存,通常更快。

当它发生时,列表构造函数将愉快地使用任何iterable,包括生成器表达式。所以:

[str(n) for n in xrange(10)]

只是“语法糖”的意思:

list(str(n) for n in xrange(10))

换句话说,列表理解只是一个生成表达式,它被转换成一个列表。

>>>''.join( str(_) for _ in xrange(10) )

这称为生成器表达式,并在PEP 289中解释。

生成器表达式和列表理解之间的主要区别在于前者不在内存中创建列表。

请注意,有第三种方法可以编写表达式:

''.join(map(str, xrange(10)))

其他回答者的回答是正确的,你发现了一个generator expression(它有一个类似于列表理解的符号,但没有包围方括号)。

一般来说,genexps(人们亲切地称之为genexps)比列表理解更有效、更快。

然而,在''.join()的情况下,列表理解速度更快,内存效率更高。原因是join需要对数据进行两次传递,因此它实际上需要一个真正的列表。如果你给它一个,它可以立即开始工作。如果给它一个genexp,它就不能开始工作,除非它在内存中通过运行genexp来构建一个新列表:

~ $ python -m timeit '"".join(str(n) for n in xrange(1000))'
1000 loops, best of 3: 335 usec per loop
~ $ python -m timeit '"".join([str(n) for n in xrange(1000)])'
1000 loops, best of 3: 288 usec per loop

当比较itertools.imapmap时,同样的结果成立:

~ $ python -m timeit -s'from itertools import imap' '"".join(imap(str, xrange(1000)))'
1000 loops, best of 3: 220 usec per loop
~ $ python -m timeit '"".join(map(str, xrange(1000)))'
1000 loops, best of 3: 212 usec per loop

相关问题 更多 >