for循环原理补充、生成器对象、yield冷门用法、生成器表达式的面试题、常见内置函数

一、for循环原理补充

使用while循环+异常处理+迭代器对象 完成for循环迭代取值的功能

l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
die_qi = l1.__iter__()
while True:
    try:
        res = die_qi.__next__()
        print(res)
    except Exception as e:
        print('数据取完了')
        break

二、生成器对象

生成器对象的本质

生成器对象其实本质上就是迭代器对象,内置有双下户线iter和双下划线next方法

区别

迭代器对象就是python解释器提供的各种数据类型或是文件对象,但是生成器对象是程序员编写的代码或是函数之类的关键字

生成器的两种形式

使用def定义函数然后内部使用yield关键字
在使用函数+yield关键字定义生成器的时候需要注意当我们使用括号调用函数的时候并没有运行这个函数,而是把这个函数体代码变成了一个生成器对象,之后我们想要调用函数产生数据就需要跟迭代器一样使用双下划线的next方法,并且每次运行的时候如果遇到yield关键字就会停止到那个位置,如果下方代码还有yield关键字,下一次运行双下划线的next方法就会运行到下一个yield关键字处停止

def my_iter():
    print('哈哈哈 椰子汁很好喝')
    yield
'''1.函数体代码中如果有yield关键字
    那么函数名加括号并不会执行函数体代码
    会生成一个生成器对象(迭代器对象)
'''
res = my_iter()
print(res)
# <generator object my_iter at 0x00000204CEDEBBA0>
'''2.使用加括号之后的结果调用__next__才会执行函数体代码'''
res.__next__()
# 哈哈哈 椰子汁很好喝

下面是多个yield的使用场景:

'''3.每次执行完__next__代码都会停在yield位置 下次基于该位置继续往下找第二个yield'''
def my_iter():
    print('哈哈哈 椰子汁很好喝')
    yield 111, 222, 333
    print('呵呵呵 从小喝到大')
    yield 111, 222, 333
    print('嘿嘿嘿 特种兵牌还可以')
    yield 111, 222, 333
    print('哼哼哼 千万别整多了 倒沫子 头发掉光光')
    yield 111, 222, 333
res = my_iter()
r1 = res.__next__()
print(r1)
r2 = res.__next__()
print(r2)
r3 = res.__next__()
print(r3)
r4 = res.__next__()
print(r4)
'''4.yield还有点类似于return 可以返回返回值'''
'''结果如下:
哈哈哈 椰子汁很好喝
(111, 222, 333)
呵呵呵 从小喝到大
(111, 222, 333)
嘿嘿嘿 特种兵牌还可以
(111, 222, 333)
哼哼哼 千万别整多了 倒沫子 头发掉光光
(111, 222, 333)
'''

注意:在上面的代码运行过程中我们也发现了yield关键字跟return一样可以返回返回值

(1)、自定义生成器对标range功能(一个参数 两个参数 三个参数 迭代器对象)

def my_range(start_num, end_num=None, step=1):
    # 判断end_num是否有值 没有值说明用户只给了一个值 起始数字应该是0 终止位置应该是传的值
    is_back = False
    if not end_num:
        # 判断第二个结束为止是否有参数,如果没有就把传给起始位置的参数给结束为止,其实位置变成0
        end_num = start_num
        start_num = 0
    if step == 0:
        yield '位移量不能为0'
    if step < 0:
        # 判断取值的步频是否为反方向
        # 如果是反方向的步频,判断起始位置和结束为止是否前面的大后面的小
        if not start_num > end_num:
            yield '参数大小错误'
        else:
            is_back = True
            # 起始位置和结束为止是前面的大后面的小的时候就返回True
    while start_num < end_num or is_back:
        # 起始位置小于结束位置的时候或是步频为负数的时候判断正确的话就输出数据值
        if start_num < end_num:
            # 起始位置小于结束位置
            print(start_num)
            yield start_num
            start_num += step
        elif is_back:
            # 步频为负数
            if start_num > end_num:
                yield start_num
                start_num += step
            else:
                is_back = False


# 定义了模仿range方法的功能后,用for循环的方式调用内部数据值

for i in my_range(100, 50, 0):
    print(i)

三、yield冷门用法

当我们使用yield关键字的时候可以用变量名绑定yield关键字,然后就可以使用send方法传参,然后会再次运行到yield关键字处停止运行

def eat(name, food=None):
    print(f'{name}准备用餐')
    while True:
        food = yield
        print(f'{name}正在吃{food}')


res = eat('kevin')
res.__next__()
res.send('汉堡')  # 1.将括号内的数据传给yield前面的变量名 2.再自动调用__next__
res.send('包子')
res.send('面条')
'''
kevin准备用餐
kevin正在吃汉堡
kevin正在吃包子
kevin正在吃面条
'''

(1)、yield与return的对比

yield
	1. 可以有返回值
	2. 函数遇到yield不会结束,只会'停住'
	3. yield关键字把函数变成了生成器,支持迭代取值了
return
	1. 可以有返回值
	2. 遇到return关键字直接结束函数运行

四、生成器表达式的面试题

"""
面试题(有难度)
	大致知道流程即可
"""
def add(n, i):  # 普通函数 返回两个数的和  求和函数
    return n + i
def test():  # 生成器
    for i in range(4):
        yield i
g = test()  # 激活生成器
for n in [1, 10]:
    g = (add(n, i) for i in g)
    """
    第一次for循环
        g = (add(n, i) for i in g)
    第二次for循环
        g = (add(10, i) for i in (add(10, i) for i in g))
    """
res = list(g)
print(res)

#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
#C. res=[20,21,22,23]
#D. res=[21,22,23,24]
'''不用深入研究 大致知道起始数即可'''"""
面试题(有难度)
	大致知道流程即可
"""


def add(n, i):
    return n + i
# 定义了一个add函数,作用求和

def test():  # 生成器
    for i in range(4):
        yield i
# 定义了一个生成器

g = test()  # 激活生成器
# 激活了生成器,这样就而已用for循环取值了
for n in [1, 10]:
    g = (add(n, i) for i in g)
    """
    第一次for循环
        这里就相当于给g重新绑定了一个生成器没有运行代码
        g = (add(n, i) for i in g)
    第二次for循环
        这里就相当于用到for循环去(add(n, i) for i in g)里面取值了,这个时候的n是10,生成器给的四个值是0、1、2、3,然后运行add就等于c选项
        g = (add(10, i) for i in (add(10, i) for i in g))
    """
res = list(g)
print(res)

# A. res=[10,11,12,13]
# B. res=[11,12,13,14]
# C. res=[20,21,22,23]
# D. res=[21,22,23,24]
'''不用深入研究 大致知道起始数即可'''

五、常见内置函数

image

# print(abs(10))
# print(abs(-10))  # 绝对值

# l = [1, 2, 3, 0]
# print(all(l))  # True
# print(any(l))

arr = range(10)

myslice = slice(5)    # 设置截取5个元素的切片

"""
    100条数据  10条  10页
    99条      10    10页
    101条      101  11
"""

# page, more=divmod(100, 10)
# page, more=divmod(99, 10)
# page, more=divmod(2005, 10)
# if more:
#     page += 1
# print(page)

# res="""print('hello world')""" #
res="""
# 这是注释
for i in range(10):
    print(i)
""" #
# eval(res) # 识别简单的python代码
# exec(res)

# if type(123) is int:
#     print('123')
# print(type('123') is int)  # 判断数据类型的
# print(isinstance('123', int))
# print(isinstance(123, int))
# print(isinstance('123', str))
# print(isinstance([1,2,3,4], list))
# print(isinstance({'a':1}, dict))

# print(chr(65))
# print(chr(97))  # 根据ASCII码表,填入对应的十进制,返回对应的字符
# print(ord('A'))
# print(ord('z'))  # 根据ASCII码表,填入对应的字符,返回对应的十进制

# l = [10, 20, 30 ,40, 50]
# print(sum(l))  # 求和

# print(pow(4, 3))  # 4 ** 3
# print(pow(2, 3))  # 4 ** 3
s = '你好啊'
# res=s.encode('utf-8')
# print(res)
# ret = res.decode('utf-8')
# print(ret)

# res=bytes(s, 'utf-8')
# print(res)
# print(str(res, 'utf-8'))

def index():
    print('from index')

# print(callable(index))  # 查看是否能够被调用

'''健壮性'''
# res=callable(index)
# if res:
#     index()
# else:
#     ''''''

# def func(name, age):
#     print(locals()) # {'name': 1, 'age': 2}
# func(1, 2)

# 复数,而不是负数
# 1+2j

# 四舍五入
print(round(3.4))
print(round(3.5))
print(round(3.6))

posted @   吴仁耀  阅读(63)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
世间美好与你环环相扣 - 柏松
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 尹初七

作曲 : 柏松

编曲 : 彭圣杰

偏偏秉烛夜游

偏偏秉烛夜游

午夜星辰 似奔走之友

爱你每个结痂伤口

酿成的陈年烈酒

入喉尚算可口

入喉尚算可口

怎么泪水 还偶尔失守

邀你细看心中缺口

裂缝中留存 温柔

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

让樱花偷偷 吻你额头

让世间美好 与你环环相扣

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

当樱花开的纷纷扬扬

当世间美好 与你环环相扣

特别鸣谢:槿葵,我们的海报制作妹妹。

原唱:柏松

吉他:柏松

和声:柏松

录音:柏松

混音:张强

点击右上角即可分享
微信分享提示