[英]Why is there a difference between the following two lines of code?
total = sum([float(item) for item in s.split(",")])
total = sum(float(item) for item in s.split(","))
第一个使用列表推导来构建所有浮点值的列表。
第二个使用生成器表达式来构建一个生成器,该生成器仅按请求构建每个浮点值,一次一个。 当列表非常大时,这可以节省大量内存。
生成器表达式也可以更快(因为它允许工作流水线,避免内存分配时间)或更慢(因为它增加了一些开销),但这通常不是在它们之间进行选择的好理由。 按照这个简单的经验法则:
如果您需要一个列表(或者,更可能的是,您可以存储的内容,多次循环,打印输出等),请构建一个列表。 如果您只需要遍历值,请不要构建列表。
在这种情况下,显然,您不需要列表,因此请关闭方括号。
在Python 2.x中,还有一些其他的细微差别; 在3.x中,列表推导实际上被定义为仅在生成器表达式上调用list
函数。 (虽然至少3.0-3.3中存在一个小错误,如果你去寻找它很难找到它...)
第一个是列表,第二个是生成器表达式。 在没有sum()
函数调用的情况下尝试它们。
In [25]: [float(a) for a in s.split(',')]
Out[25]: [1.23, 2.4, 3.123]
In [26]: (float(a) for a in s.split(','))
Out[26]: <generator object <genexpr> at 0x0698EF08>
In [27]: m = (float(a) for a in s.split(','))
In [28]: next(m)
Out[28]: 1.23
In [29]: next(m)
Out[29]: 2.4
In [30]: next(m)
Out[30]: 3.123
因此,第一个表达式首先在内存中创建整个列表,然后计算总和,而第二个表达式只获取表达式中的下一个项目并将其添加到当前总计中。 (更高效的内存)
正如其他人所说,第一个创建一个列表,而第二个创建一个生成所有值的生成器。 您可能关心这一点的原因是创建列表会立即将所有元素放入内存中,而使用生成器,您可以在生成它们时处理它们而无需将它们全部存储起来,这对于非常大量的数据可能很重要。
第一个创建一个列表,并将列表中的数字相加。 它是一个总和中的列表理解
第二个项依次计算每个项目并将其添加到运行总计中,并在所有项目都用完时将运行总计作为总和返回。 这是一种生成器理解。
它根本不创建列表,这意味着它不需要额外的时间来为列表分配内存并填充它。 这也意味着它具有更好的空间复杂性,因为它只使用常量空间(对于float
调用;除了调用split
,这两行都行)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.