Python中的生成式与生成器

#########生成式与生成器的理解#########

##列表生成式的理解

1,列表生成式使用变形简单列举

1)用列表表示1-10所有偶数的平方

print([i ** 2 for i in range(2, 11, 2)])
def fun(num):
    num = num ** 2
    return num
print([fun(i) for i in range(2, 11, 2)])

2)用列表表示1-10所有偶数中能被三整除的数的平方

def fun(num):
    num = num ** 2
    return num


print([fun(i) for i in range(2, 11, 2) if i % 3 == 0])

3)用列表表示1-10里面偶数和奇数的运算

def fun1(num):
    num=num**2
    return num
def fun2(num):
    num=num**3
    return num
def fun3(num):
    # if num%2==0:
    #     return True
    # else:
    #     return False
    return num%2==0

print([fun1(i) if fun3(i) else fun2(i)  for i in range(1, 10)])

 

##列表生成式经典例题在线

- 题目描述:

给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输
入值小于1000。
如,输入为10, 程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))
# [2,3,5,7]

解答:

sushudui = 0
a = int(input('输入一个小于1000的正整数:'))


def issushu(a):
    for i in range(2, a):
        if a % i == 0:
            return False
    else:
        return True


list = [i for i in range(2, a + 1) if issushu(i)]
for j in list:
    if (a - j) in list and j <= a - j:
        sushudui += 1
print('共有%d对素数对' %sushudui)

题目描述:

求下列矩阵的转置矩阵
    [1,2,3,3,4]
    [4,5,6,2,1]
    [7,8,9,1,2]

 

解答:

li = [
    [1, 2, 3, 3, 4],
    [4, 5, 6, 2, 1],
    [7, 8, 9, 1, 2]
]

print([[raw[i] for raw in li] for i in range(5)])

##集合生成式的理解

相同于列表生成式,集合生成式同样也可以实现,如下:

s = {1, 2, 3, 4, 5, 6, 7, 8, 9}
set = {i**2 for i in s}
print(set)

##字典生成式的理解

需求1: 假设有20个学生,学生分数在60-100之间,筛选出成绩在90分以上的学生

import random

set = {}
scoreset = {}
for i in range(20):
    # name = 'student' + str(i)
    # score = random.randint(60, 100)
    # set[name] = score
    set['student' + str(i)] = random.randint(60, 100)

# for name, score in set.items():
#     if score > 90:
#         scoreset[name] = score
# print(scoreset)

print({name: score for name, score in set.items() if score > 90})

需求2:将字典的key值和value值调换

dict = {'a': '123', 'b': '456', 'c': '789'}
print({v: k for k, v in dict.items()})

##生成器的理解

#生成器

   我们在使用python生成迭代器的过程中,如果数据很大,会受到内存和处理速度的限制。而生成器是一个简单的方式来完成迭代。简单来说,Python的生成器是一个返回可以迭代对象的函数。

     在一个一般函数中使用yield关键字,可以实现一个最简单的生成器,此时这个函数变成一个生成器函数。yieldreturn返回相同的值,区别在于return返回后,函数状态终止,而yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

#生成器特点的理解

输入代码:

def fun():
    print('step 1')
    yield "yield1"
    print('step 2')
    yield 'yield2'
    print('step3')
    res = yield 'yield3'  # res = "hello"
    print("生成器接收了一个值:", res)
    yield "yield4"
g = fun()
print(g)

下面我们来依次判断:

# 函数中有yield, 返回值是一个生成器.

# 生成器函数默认不执行函数内容, 当next(g)时, 才执行函数内容.

# 执行函数时, 一直执行, 遇到yield停止。 默认情况不会显示yield后面的内容,如果要显示print(next(g))

# 如果需要给生成器函数传值
#       1). 必须有变量接收传递的值: res = yield 'yield3'
#       2). 通过g.send("hello")
#       3). send方法, 给yield所在位置传值, 接收值之后, 直到遇到yield停止.

 

# 斐波那契数列(Fibonacci sequence)

** 历史
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)
以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,
斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963年起出版了以
《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。


** 数列内容
斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,
610,987,1597,2584,4181,6765,10946,17711,28657,46368........

# yield: 当函数中包含yield关键字, 返回值是一个生成器, 如果要执行函数内容.需要调用next方法, 或者for循环.
#         运行过程: 当执行next方法时, 遇到yield程序停止, 直到执行下一次next方法时,
#          从上一次停止的yield处继续执行,遇到yield停止运行.
# return: 遇到return函数执行结束;

# num=1
def fib(num):
    """将来显示几个fib数列"""
    # count代表显示的已经
    # a代表第一个数, b代表第二个数, count代表已经显示的fib个数,当前为0.
    a,b,count = 0,1,0
    # 如果当前显示的个数小于需要显示的格式, 则显示b, 并且计算出下一个要显示的数。
    while count < num:
        yield  b
        a, b = b, a+b
        # 已经显示的次数加1;
        count += 1


# 生成器: 如果函数中有yield, 那么这个函数的返回值就是一个生成器;
res=fib(100)
print(next(res))
print(next(res))


# 生成器fib()执行的过程分析:
#       执行语句 f = fab(100) 时,并不会马上执行 fib() 函数的代码块,而是首先返回一个 iterable 对象(即生成器)!
#       在 for 循环语句执行时或者next(),才会执行 fib() 函数的代码块。
#       执行到语句 yield b 时,fib() 函数会返回一个迭代值,直到下次迭代前,
#       程序会回到 yield b 的下一条语句继续执行,然后再次回到 for 循环,如此迭代直到结束。
#       看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
# 由此可以看出,生成器通过关键字 yield 不断的将迭代器返回到内存进行处理,而不会一次性的将对象全部放入内存,
# 从而节省内存空间。

################################

猜你喜欢

转载自blog.csdn.net/houzeyu666/article/details/81843033
今日推荐