python - 加入字符串。生成器或列表理解?

标签 python

考虑从一个巨大的字符串中提取字母表的问题。

一种方法是

''.join([c for c in hugestring if c.isalpha()])

机制很明确:列表理解生成一个字符列表。 join 方法通过访问列表的长度知道它需要加入多少个字符。

其他方法是

''.join(c for c in hugestring if c.isalpha())

此处生成器理解生成生成器。 join 方法不知道它要连接多少个字符,因为生成器不具有 len 属性。所以这种join方式应该比list comprehension方式慢。

但是在 python 中测试表明它并不慢。为什么会这样? 任何人都可以解释 join 如何在生成器上工作。

要清楚:

sum(j for j in range(100))

不需要知道 100,因为它可以跟踪累计和。它可以使用生成器上的 next 方法访问下一个元素,然后添加到累积和。 但是,由于字符串是不可变的,因此累积连接字符串会在每次迭代中创建一个新字符串。所以这会花费很多时间。

最佳答案

当您调用 str.join(gen) 时,其中 gen 是一个生成器,Python 在开始之前执行与 list(gen) 等效的操作继续检查结果序列的长度。

具体来说,如果你 look at the code implementing str.join in CPython ,你会看到这个电话:

    fseq = PySequence_Fast(seq, "can only join an iterable");

调用 PySequence_Fastseq 参数转换为列表(如果它还不是列表或元组的话)。

因此,您调用的两个版本的处理方式几乎相同。在列表理解中,您自己构建列表并将其传递给 join。在生成器表达式版本中,您传入的生成器对象会在 join 开始时变成一个 list,其余代码对两个版本的操作相同..

关于python - 加入字符串。生成器或列表理解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34822676/

相关文章:

python - 编译UWSGI Empire_mongodb插件

python - 如何将 header 添加到 python 中的 Bokeh 仪表板?

python - 一个列表与另一个列表的排列组合

python - 在 Python 中获取计时器刻度

python - 如何获取 pandas 中某个项目的第一次和最后一次出现

data-structures - Python:修改列表元素的正确方法是什么?

javascript - 通过scrapy python中的javascript与splash实现下一页?

python - Celery:有没有办法编写自定义 JSON 编码器/解码器?

python - 无法修改 numpy 数组

python - 如何在 python 单元测试中模拟特定文件的存在?