python3:生成器(generator)和推导式


1、推导式

1.1 列表推导式

# 列表推导式

"""
列表推导式:最终得到的是一个列表:
格式:
    lst = [i for i in range(100)]
    lst = [i for i in range(100) if 条件]
    lst = [i if 条件1 else 条件2 for i in range(100) ]

"""

# 传统
lst = []
for i in range(20):
    lst.append(i)
print(lst)

# 列表推导式
lst = [i for i in range(20)]
print(lst)

lst = [i + 2 for i in range(20)]  # 格式一
print(lst)

lst = [i for i in range(0, 101, 2)]  # 格式一
print(lst)

lst = [i for i in range(101) if i % 2 == 0]  # 格式二:带判断条件
print(lst)

lst2 = ['62', 'hello', '100', 'world', 'luck', '88']
lst = [word for word in lst2 if word.isalpha()]  # 全部是字母组成的新单词
print(lst)

# 如果是h开头的首字母大写,如果不是h开头的则全部转成大写  if else

lst = [word.title() if (word.isalpha() and word.startswith('h'))
       else word.upper()
       for word in lst2]
print(lst)

# 2层for 循环

lst3 = [(i, j) for i in range(5) for j in range(5)]  # 2层for循环
print(lst3)

# 实现将1-100 中的数字3个一组如[[1,2,3],[4,5,6]...]
lst = [[i, i + 1, i + 2] if i < 100 else [i] for i in range(1, 101, 3)]
print(lst)

nei_lst = [i for i in range(1, 101)]
lst = [nei_lst[i:i + 3] for i in range(0, len(nei_lst), 3)]
print(lst)


# 推导式
"""
列表推导式、字典推导式、集合推导式
    旧列表----->新列表
格式
    列表推导式:
        格式:[表达式 for 变量 in 旧列表] 或者[表达式 for 变量 in 旧列表 if 条件]
    双层嵌套:
        [表达式 for 变量 in 旧列表 if 条件 for 变量 in 旧列表 if 条件]
"""

print("列表推导式".center(30, "*"))
names = ["sanduo", 'lily', 'jack', 'bob']

# 过滤长度小于3的任命

result = [name for name in names if len(name) > 3]
print(result)

# 首字母大写
capitalize_result = [name.capitalize() for name in names if len(name) > 3]
print(capitalize_result)
# for if


# 1-100之间能被3整除的,组成一个列表

new_list = [i for i in range(1, 101) if i % 3 == 0 and i % 5 == 0]

print(new_list)

# for if  for if
# 0-10之间的偶数和奇数组成元组列表,例如:(偶数,奇数)
# new_tuple = [tup for i in range(5) if i % 2 == 0]
# new_tuple = [tup for j in range(5) if j % 2 == 1]
new_tuple = [(i, j) for i in range(10) if i % 2 == 0 for j in range(10) if j % 2 == 1]
print(new_tuple)

# lst = [[1,2,3],[4,5,6],[7,8,9],[1,3,5]] ->[3,6,9,5]
lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [1, 3, 5]]
new_lst = [x[-1] for x in lst]
print(new_lst)

# if eles
dic1 = {'name': 'tom', 'salary': 9000}
dic2 = {'name': 'lucy', 'salary': 4000}
dic3 = {'name': 'jack', 'salary': 10000}
dic4 = {'name': 'lily', 'salary': 3000}

lst2 = [dic1, dic2, dic3, dic4]

#  如果薪资大于5000,+200;低于等于5000 +500;

lst3_new = [item["salary"] + 500 if item["salary"] <= 5000 else item["salary"] + 200 for item in lst2]
print(lst3_new)

lst4_new = [item.get("salary") + 500 if item.get("salary") <= 5000 else item.get("salary") + 200 for item in lst2]
print(lst4_new)

lst5_new = [{'name': item['name'], 'salary': item["salary"] + 500} if item["salary"] <= 5000
            else {'name': item['name'], 'salary': item["salary"] + 200} for item in lst2]

print(lst5_new)

1.2 字典推导式

# 字典推导式


dict1 = {'a': 'A', 'b': "B", 'c': 'C', 'd': 'C'}

# 将值和键进行交换

dict2 = {v: k for k, v in dict1.items()}  # 取最后一个
print(dict2)

1.3 集合推导式

# 集合推导式{}  类似与列表推导式,在列表推导式基础上,去重重复项功能

lst = [1, 2, 3, 1, 3, 4, 5, 3, 7, 8, 5]

# 去重
set1 = {item for item in lst}
print(set1)
set3 = {item+1 for item in lst if item >5}
print(set3)

2、生成器代器

2.1、生成器基本操作

# 生成器 ()

"""
通过列表生成式(列表推导式),我们可以直接创建一个列表:
    但是,收到内容容量限制,列表容量肯定是有限的。而且创建一个包含100万元素的列表,不仅占用很大的内存空间。
    如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
    这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,成为生成器:generator
得到生成器的方式:
    1、列表推导式得到生成器:
        g = (x+1 for x in range(10))
    2、借助函数完成
        (1) 定义一个函数,函数中使用yield关键字
                def gen():
                    ...
                    yield
                g = gen()
        (2) 调用函数,接受调用的结果
        (3) 得到的结果就是生成器
        (4) 借助next() 或者__next__()获取
    3、产生元素:
        (1) next(generator) ----->每次调用都会产生一个新的元素,如果元素产生完毕再次调用的化就会产生异常
        (2) 成器方法:
            g.__next__()
            g.send(value)
    4、应用领域:协程
注意:
    只要函数中出现yield(生成)关键字,说明函数就不是函数拉,变成生成器了

生成器方法:
    __next__() :  获取下一个元素
    send(value): 每次生成器调用中传值的;注意第一次调用传递一个send(None)


"""
# 牺牲时间换空间
# x = [x for x in range(1000000000000000000000000000000000000)]

new_lst = [x * 3 for x in range(10)]
print(new_lst)

# 生成器()

g_lst = (x * 3 for x in range(10))  # 最多10个超过,就报错:StopIteration
print(type(g_lst))  # <class 'generator'>
print(g_lst)
print(g_lst.__next__())
# 没调用一次产生一个元素
print(next(g_lst))

while True:
    try:
        print(next(g_lst))
    except StopIteration:
        print("元素已经取完!")
        break


# 测试函数生成器


def func():
    n = 0
    while True:
        n += 1
        print(n)
        yield n  # 表示是生成器


x = func()  # <generator object func at 0x000002440E14EAC8>
print(x)
print(next(x))

print("斐波那契数列".center(30, '*'))


# 斐波那契数列 n ,m , n+m

def fibonacci():
    a, b = 0, 1
    n = 0
    while True:
        print(b)
        yield b
        a, b = b, a + b
        n += 1


m = 10
y = fibonacci()

while m > 0:
    next(y)
    m -= 1
print("yield".center(30, '#'))


def tep():
    i = 0
    while i < 5:
        temp = yield i
        print('temp', temp)
        for x in range(temp):
            print("------------------", x)
        print("***************")
        i += 1
    return '没有更多的数据'


g = tep()
# print(next(g))
# print(next(g))
# print(next(g))

# g.__next__()
n = g.send(None)
print("n", n)
n1 = g.send(3)  # TypeError: can't send non-None value to a just-started generator
print("n1", n1)
n2 = g.send(5)
print("n2", n2)

2.2、生成器应用(进程、线程、协程)

# 生成器应用:应用多个任务,协程   进程->线程->协程 
"""
 进程 : 下载1G电影
 线程 :分了10份,每份100M
 协程 : 做任务,多个任务之间快速切换
"""


# 类如迅雷:

def task1(n):
    for i in range(n):
        print("正在搬第{}块砖".format(i))
        yield None


def task2(n):
    for i in range(n):
        print("正在听第{}首歌".format(i))
        yield None


g1 = task1(10)
g2 = task2(5)

# 模拟协程 多个任务之间快速切换
while True:
    try:  # 交替完成
        g1.__next__()
        g2.__next__()
    except StopIteration:
        break


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值