加入列表:
>>> ''.join([ str(_) for _ in xrange(10) ]) '0123456789'
join 必须采取迭代。
显然,join的论点是[ str(_) for _ in xrange(10) ],这是一个列表理解。
[ str(_) for _ in xrange(10) ]
看这个:
>>>''.join( str(_) for _ in xrange(10) ) '0123456789'
现在,join的参数为just str(_) for _ in xrange(10),no [],但结果相同。
just str(_) for _ in xrange(10),no []
为什么?是否str(_) for _ in xrange(10)还会产生列表或可迭代项?
(_) for _ in xrange(10)
>>>''.join( str(_) for _ in xrange(10) )
这称为生成器表达式,并在PEP 289中进行了说明。
生成器表达式和列表理解之间的主要区别在于前者不在内存中创建列表。
请注意,还有第三种编写表达式的方法:
''.join(map(str, xrange(10)))
其他回答的正确回答是你发现了一个生成器表达式(该表达式的表达与列表推导类似,但没有方括号)。
通常,genexps(众所周知)与列表理解相比,具有更高的存储效率和速度。
genexps
但是,在''.join()列表推导的情况下,它更快,内存使用效率更高。原因是联接需要对数据进行两次传递,因此它实际上需要一个真实的列表。如果你给它一个,它可以立即开始工作。如果你给它一个genexp,它将无法开始工作,直到它通过运行genexp到穷竭在内存中建立一个新列表:
''.join()
~ $ 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.imap和map时,结果相同:
~ $ 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