在函数中使用时,列表推导中不需要方括号 [英] Square braces not required in list comprehensions when used in a function

查看:57
本文介绍了在函数中使用时,列表推导中不需要方括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码提交了拉取请求:

I submitted a pull request with this code:

my_sum = sum([x for x in range(10)])

一位评论者建议这样做:

One of the reviewers suggested this instead:

my_sum = sum(x for x in range(10))

(区别只是缺少方括号).

(the difference is just that the square braces are missing).

我对第二种形式似乎完全相同感到惊讶.但是,当我尝试在第一个可行的其他环境中使用它时,它会失败:

I was surprised that the second form seems to be identical. But when I tried to use it in other contexts where the first one works, it fails:

y = x for x in range(10)
        ^ SyntaxError !!!

两种形式是否相同?为什么在函数中不需要方括号有什么重要的原因吗?还是这只是我必须知道的事情?

Are the two forms identical? Is there any important reason for why the square braces aren't necessary in the function? Or is this just something that I have to know?

推荐答案

这是一个生成器表达式.要使其在独立情况下正常工作,请使用花括号:

This is a generator expression. To get it to work in the standalone case, use braces:

y = (x for x in range(10))

和y成为生成器.您可以遍历生成器,因此可以在需要可迭代的地方使用它,例如sum函数.

and y becomes a generator. You can iterate over generators, so it works where an iterable is expected, such as the sum function.

用法示例和陷阱:

>>> y = (x for x in range(10))
>>> y
<generator object <genexpr> at 0x0000000001E15A20>
>>> sum(y)
45

在保持发电机周围时要小心,您只能通过它们一次.因此,在执行完上述操作后,如果再次尝试使用sum,则会发生这种情况:

Be careful when keeping generators around, you can only go through them once. So after the above, if you try to use sum again, this will happen:

>>> sum(y)
0

因此,如果您传递的生成器实际上期望包含列表或集合或类似内容,则必须小心.如果函数或类存储参数并尝试对其进行多次遍历,则会遇到问题.例如,考虑一下:

So if you pass a generator where actually a list or a set or something similar is expected, you have to be careful. If the function or class stores the argument and tries to iterate over it multiple times, you will run into problems. For example consider this:

def foo(numbers):
    s = sum(numbers)
    p = reduce(lambda x,y: x*y, numbers, 1)
    print "The sum is:", s, "and the product:", p

如果将其交给生成器,它将失败:

it will fail if you hand it a generator:

>>> foo(x for x in range(1, 10))
The sum is: 45 and the product: 1

您可以轻松地从生成器生成的值中获取列表:

You can easily get a list from the values a generator produces:

>>> y = (x for x in range(10))
>>> list(y)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

您可以使用它来修复前面的示例:

You can use this to fix the previous example:

>>> foo(list(x for x in range(1, 10)))
The sum is: 45 and the product: 362880

但是请记住,如果从生成器构建列表,则将需要存储每个值.在您有很多项目的情况下,这可能会占用更多的内存.

However keep in mind that if you build a list from a generator, you will need to store every value. This might use a lot more memory in situations where you have lots of items.

为什么要使用发电机?

更低的内存消耗是sum(generator expression)优于sum(list)的原因:生成器版本仅需要存储一个值,而列表变量必须存储N个值.因此,应始终在不冒副作用的情况下使用发生器.

The much lower memory consumption is the reason why sum(generator expression) is better than sum(list): The generator version only has to store a single value, while the list-variant has to store N values. Therefore you should always use a generator where you don't risk side-effects.

这篇关于在函数中使用时,列表推导中不需要方括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆