简体   繁体   English

使用生成器代替嵌套循环

[英]Using generator instead of nested loops

I have the following nested loop.我有以下嵌套循环。 But it is inefficient time wise.但在时间上效率低下。 So using a generator would be much better.所以使用发电机会好得多。 Do you know how to do that?你知道怎么做吗?

x_sph[:] = [r*sin_t*cos_p for cos_p in cos_phi for sin_t in sin_theta for r in p]     

It seems like some of you are of the opinion (looking at comments) that using a generator was not helpful in this case.似乎你们中的一些人认为(查看评论)在这种情况下使用生成器没有帮助。 I am under the impression that using generators will avoid assigning variables to memory, and thus save memory and time.我的印象是使用生成器将避免将变量分配给内存,从而节省内存和时间。 Am I wrong?我错了吗?

Judging from your code snippet you want to do something numerical and you want to do it fast.从你的代码片段来看,你想做一些数字化的事情并且你想快速完成。 A generator won't help much in this respect.发电机在这方面没有多大帮助。 But using the numpy module will.但是使用numpy模块会。 Do it like so:这样做:

import numpy
# Change your p into an array, you'll see why.
r = numpy.array(p) # If p is a list this will change it into 1 dimensional vector.
sin_theta = numpy.array(sin_theta) # Same with the rest.
cos_phi = numpy.array(cos_phi)

x_sph = r.dot(sin_theta).dot(cos_phi)

In fact I'd use numpy even earlier, by doing:事实上,我会更早地使用numpy ,方法是:

phi = numpy.array(phi) # I don't know how you calculate this but you can start here with a phi list.
theta = numpy.array(theta)

sin_theta  =numpy.sin(theta)
cos_phi = numpy.cos(phi)

You could even skip the intermediate sin_theta and cos_phi assignments and just put all the stuff in one line.您甚至可以跳过中间的sin_thetacos_phi赋值,而将所有内容放在一行中。 It'll be long and complicated so I'll omit it but I do numpy -maths like that sometimes.它会很长而且很复杂,所以我会省略它,但有时我会做这样的numpy -maths。

And numpy is fast, it'll make a huge difference. numpy很快,它会产生巨大的不同。 At least a noticeable one.至少是一个引人注目的。

[...] creates a list and (...) a generator : [...]创建一个列表和(...)一个生成器:

generator = (r*sin_t*cos_p for cos_p in cos_phi for sin_t in sin_theta for r in p)
for value in generator:
    # Do something

To turn a loop into a generator, you can make it a function and yield :要打开一个循环变成一台发电机,你可以把它的功能和yield

def x_sph(p, cos_phi, sin_theta):
    for r in p:
        for sin_t in sin_theta:
            for cos_p in cos_phi:
                yield r * sin_t * cos_p

However, note that the advantages of generators are generally only realised if you don't need to calculate all values and can break at some point, or if you don't want to store all the values (the latter is a space rather than time advantage).但是,请注意,生成器的优势通常只有在您不需要计算所有值并且可能在某个时刻break ,或者您不想存储所有值(后者是一个空间而不是时间)时才能实现优势)。 If you end up calling this:如果你最终调用这个:

lst = list(x_sph(p, cos_phi, sin_theta))

then you won't see any gain.那么你将看不到任何收益。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM