考虑从巨大的字符串中提取字母表的问题.
一种方法是
''.join([c for c in hugestring if c.isalpha()])
Run Code Online (Sandbox Code Playgroud)
机制很明确:列表理解生成一个字符列表.join方法通过访问列表的长度来了解它需要加入多少个字符.
其他方法是
''.join(c for c in hugestring if c.isalpha())
Run Code Online (Sandbox Code Playgroud)
这里发电机理解产生发电机.join方法不知道要加入多少个字符,因为生成器不具有len属性.所以这种连接方式应该比列表理解方法慢.
但是在python中测试表明它并不慢.为什么会这样?任何人都可以解释加入如何在发电机上工作.
要明确:
sum(j for j in range(100))
Run Code Online (Sandbox Code Playgroud)
不需要知道100,因为它可以跟踪累积总和.它可以使用生成器上的下一个方法访问下一个元素,然后添加到累积和.但是,由于字符串是不可变的,因此累加连接字符串会在每次迭代中创建一个新字符串.所以这需要很多时间.
Blc*_*ght 12
当你调用str.join(gen)where gen是一个生成器时,Python list(gen)会在继续检查结果序列的长度之前做相同的操作.
具体来说,如果你看一下str.join在CPython中实现的代码,你会看到这个调用:
fseq = PySequence_Fast(seq, "can only join an iterable");
Run Code Online (Sandbox Code Playgroud)
如果参数不是列表或元组,PySequence_Fast则将seq参数转换为列表的调用.
因此,您的两个版本的呼叫几乎完全相同.在列表理解中,您自己构建列表并将其传递给join.在生成器表达式版本中,传入的生成器对象在开始时变为list右侧,join其余代码对两个版本的操作都相同.
| 归档时间: |
|
| 查看次数: |
2573 次 |
| 最近记录: |