生成器 python&golang

来源:互联网 发布:知乎怎么发布话题 编辑:程序博客网 时间:2024/06/06 20:06

生成器

编程中常遇到这样的问题,要生成一个大的列表或把一个大文件读入内存. 如果一次性把大的列表或数组生成出来,或把文件读入内存中,将十分消耗内存资源.

现在有这样一个问题, 要生成一千万个随机整数, 并求和.
解决思路有两种,第一种: 先生成一千万个随机整数,然后遍历求和.
第二种: 每生成一个随机整数,求一次和.
显然是第二种方式比较省内存. 使用生成器就可以完美的实现.

python的生成器

获得生成器

在python中有两种获得生成器的方式:
第一种: ()
和列表生成式[i for i in range(10)]很像. 列表生成式返回的是list, 而这个返回值是generator.

gen = (random.randint(1, 100) for i in range(1000 * 10000))

第二种: yield
函数中存在yield关键字是, 函数返回值是一个generator.

def random_lst(n):    for i in range(n):        yield random.randint(1, 100)

使用生成器

# 生成器函数def random_lst(n):    for i in range(n):        yield random.randint(1, 100)gen = random_lst(1000 * 10000)  # 一千万个随机数的生成器s = 0for i in gen:  # for in 遍历生成器    s += iprint(s)

golang 使用channel实现生成器

package mainimport (    "fmt"    "math/rand"    "time")func main() {    ch := make(chan int, 1)  // ch的大小设置为1,这样生成一个就处理一个    go random_list(10, ch)  // 这里要使用goroutine    // 求和    s := 0    for i := range ch {        fmt.Println(i)        s += i    }    fmt.Println(s)}// 模拟生成器func random_list(n int, result chan int){    rand.Seed(time.Now().UnixNano())    for i := 0; i < n; i++ {        result <- rand.Intn(100)    }    close(result)}

python实现斐波拉契数列(Fibonacci)

def fib(max):    n, a, b = 0, 0, 1    while b < max:        yield b        n = n + 1        a, b = b, a+b

golang实现斐波拉契数列(Fibonacci)

func fib(max int, result chan int){    n, a, b := 0, 0, 1    for n < max {        result <- b  // 将生成的数字放入result中        n = n + 1        a, b = b, a+b    }    close(result)}