考虑从一个巨大的字符串中提取字母表的问题。
一种方法是
''.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_Fast
将 seq
参数转换为列表(如果它还不是列表或元组的话)。
因此,您调用的两个版本的处理方式几乎相同。在列表理解中,您自己构建列表并将其传递给 join
。在生成器表达式版本中,您传入的生成器对象会在 join
开始时变成一个 list
,其余代码对两个版本的操作相同..
关于python - 加入字符串。生成器或列表理解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34822676/