目录

  • 认识列表推导式
  • 集合推导式
  • 生成器
  • 生成器二
  • 应用
  • 生成器获取元素
  • 应用
  • 迭代器


认识列表推导式

#列表推导式
# 旧的列表---》新的列表
'''
1.列表推导式: 格式1:[返回的东西 for 变量 in 旧列表]
             格式2:[返回的东西 for 变量 in 旧列表 if 条件]
字典推导式
集合推导式

'''
#过滤长度小于等于3的人名
names=['tom','lily','abc','jack','steven','bob']
result=[name for name in names if len(name)>3]
print(result)#['lily', 'jack', 'steven']


'''
def func(names):
    newlist=[]
    for name in names:
        if len(name)>3:
            newlist.append(name)
    return newlist
'''



#for name in names if len(name)>3 符合条件的元素的name.capitalize()添加到一个新列表里
result=[name.capitalize() for name in names if len(name)>3]
print(result)#['Lily', 'Jack', 'Steven']


#将1-20之间能被3整除,组成一个新的列表
result=[i for i in range(1,21) if i%3==0]
print(result)#[3, 6, 9, 12, 15, 18]

#元组第一个数字为0-5之间的偶数,第二个数字为0-5之间的奇数
#[(偶数,奇数),(),()]  [(0,1),(0,3),(0,5),(2,1),(2,3)]
newlist = [(x,y) for x in range(6) if x%2==0 for y in range(6) if y%2!=0]
print(newlist)
#[(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
'''
def func():
    newlist=[]
    for i in range(6):
        if i%2==0:
            for j in range(6):
                if j%2!=0:
                    newlist.append((i,j))
    return newlist
'''

#list1=[[1,2,3],[4,5,6],[7,8,9],[1,3,5]]-->[3,6,9,5]
list1=[[1,2,3],[4,5,6],[7,8,9],[1,3,5]]
newlist=[i[-1] for i in list1]
print(newlist)


#如果薪资大于5000则加200,小于等于5000则加500
dict1={'name':'tom','salary':5000}
dict2={'name':'lucy','salary':8000}
dict3={'name':'jack','salary':4500}
dict4={'name':'lily','salary':3000}

list1=[dict1,dict2,dict3,dict4]
newlist=[employee['salary']+200 if employee['salary']>5000 else employee['salary']+500 for employee in list1  ]
print(newlist)#[5500, 8200, 5000, 3500]

'''
if单独使用只能放在后面
if else配套使用只能放在前面   if条件成立执行其前面的,不成立则执行其后面的
'''

集合推导式

#集合推导式
set1={1,2,1,3,5,2,1}
# print(type(set1))
set1={x+1 for x in set1}
print(set1)

set2={1,2,1,3,5,2,1,8,9,8,9,7}
set2={x for x in set2 if x>5}
print(set2)
'''
{2, 3, 4, 6}
{8, 9, 7}
'''

#字典推导式
dict1={'a':'A','b':'B','c':'C','d':'C'}
print(dict1.items())
newdict={value:key for key,value in dict1.items()}
print(newdict)
'''
dict_items([('a', 'A'), ('b', 'B'), ('c', 'C'), ('d', 'C')])
{'A': 'a', 'B': 'b', 'C': 'd'}
'''

生成器

#定义生成器得方式一   圆括号

'''
通过列表推导式,我们可以直接创建一个列表
但是,受到内存的限制,列表容量肯定是有限的
而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间
如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量的空间
在python中,这种一边循环一边计算的机制,称为生成器

'''
#列表推导式
newlist = [x*3 for x in range(5)]
print(newlist)#[0, 3, 6, 9, 12]

#生成器用圆括号表示,#大括号有可能是集合推导式也可能是字典推导式,方括号是列表推导式,圆括号是生成器
g=(x*3 for x in range(5))
print(type(g))#<class 'generator'>

#得到元素的两种方式
print(g.__next__())
print(g.__next__())
print(next(g))
print(next(g))
'''
0
3
6
9
'''
print(next(g))

#下面一句超过了能取得范围
# print(next(g))
'''
Traceback (most recent call last):
  File "D:/pythonFile/hanshu/generatorr7/func03.py", line 31, in <module>
    print(next(g))
StopIteration
'''

q=(x for x in range(6))
while True:
    try:
        e=next(q)
        print(e)
    except:
        print('没有更多元素拉!')
        break
'''
0
1
2
3
4
5
没有更多元素拉!

'''

生成器二

#定义生成器得方式二   函数
#只要函数中出现yield关键字,说明这是个生成器而不是一个函数
'''
步骤:
1.定义一个函数,函数中使用yield关键字
2.调用函数,接收调用得结果
3.得到得结果就是生成器g
4.借助于next(g)/g.__next__()得到元素

'''


def func():
    n=0
    while True:
        n+=1
        yield n  #==>return n+暂停程序  第一次到这他会返回n然后暂停自己,去执行print(g.__next__()),然后又回来继续这个while循环,实现n+=1
g=func()  #调用函数,函数返回一个生成器
print(g)

print(g.__next__())
print(next(g))
'''
<generator object func at 0x00000286E1B25AF0>
1
2
'''

应用

#斐波那契数列
# 0 1 1 2 3 5 8 13 21
# def fib(length):#length代表要输出几个
#     a,b = 0,1
#     n=0
#
#     while n < length:
#         yield b
#         a,b=b,a+b
#         n+=1
#     return '没有更多元素'#这里得文字在越界读取报错时会显示
#
# g = fib(4)
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
'''
Traceback (most recent call last):
  File "D:/pythonFile/hanshu/generatorr7/func05.py", line 18, in <module>
    print(next(g))
StopIteration: 没有更多元素
'''

print('----------------------------------')
def gen():
    i=0
    while i<5:
        temp = yield i #return i+暂停
        print('temp',temp)
        i+=1
    return '没有更多数据'

g=gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
'''
0
temp None
1
temp None
2
temp None
3
temp None
4
temp None
Traceback (most recent call last):
  File "D:/pythonFile/hanshu/generatorr7/func05.py", line 41, in <module>
    print(next(g))
StopIteration: 没有更多数据

Process finished with exit code 1

'''
def gen():
    i=0
    while i<5:
        temp = yield i
        print(temp)
        print('temp',temp)
        i+=1
    return '没有更多的元素'
g=gen()
g.send(None)#这里才是真正的第一次调用,与next(g)作用相似,只是这里可以给temp复制
n1=g.send('哈哈')
print('n1:',n1)
n2=g.send('呵呵')
print('n2:',n2)

生成器获取元素

'''
生成器获取元素方法
g.__next__()
next(g)
send('xx')#可以给上次暂停在yield处赋值返回值xx,由于第一次调用不会又、有上次暂停,因此一次调用send(None)

'''
def gen():
    i=0
    while i<5:
        temp = yield i#return i +暂停x
        print('temp:',temp)
        for x in range(temp):
            print('--->',)
        print('*****************')
        i+=1
    return '没有更多数据'

g=gen()
print(g.send(None))
n1=g.send(3)
print('n1:',n1)
n2=g.send(5)
print('n2:',n2)

应用

#生成器的应用
#进程>线程>协程
#一个线程有多个协程---每个协程下有自己的任务

#搬一块砖听一首歌
def task1(n):
    for i in range(n):
        print('正在搬第{}块砖'.format(i))
        yield#每次执行到这就暂停  由于yield后面没接变量,因此不return

def task2(n):
    for i in range(n):
        print('正在听第{}首歌'.format(i))
        yield None#暂停不return

#得到生成器
g1=task1(5)
g2=task2(5)
while True:
    try:
        g1.__next__()
        g2.__next__()
    except:
        break


'''
正在搬第0块砖
正在听第0首歌
正在搬第1块砖
正在听第1首歌
正在搬第2块砖
正在听第2首歌
正在搬第3块砖
正在听第3首歌
正在搬第4块砖
正在听第4首歌
'''
'''
总结生成器:
定义生成器的方式:
#取代列表推导式,列表推导式每次生成全部,占用内存,生成器只有在需要用的时候才生成next(g)...
1.类似列表推导式(旧列表--新列表),但是它是用()的
    g=(x+1 for x in range(6))
2.借助函数+yield
    def func():
        ...
        yield
    g=func()#得到生成器
    #产生元素(每次调用产生一个新元素,如果元素产生完毕,再次调用会产生异常)
    next(g)
    g.__next__()
    g.send('xx')
    
3.生成器的应用---协程
    
'''

迭代器

#迭代器&可迭代对象
#可迭代对象:1.生成器 2.元组 列表 集合 字典 字符串

#如何判断一个对象是否是可迭代?
from collections import Iterable

list1=[1,4,7,8,8]
f=isinstance(list1,Iterable)#判断list1是否是可迭代的
print(f)#True

print(isinstance('abc',Iterable))#True

print(isinstance(3,Iterable))#False

#生成器是否是可迭代的
g=(x+1 for x in range(10))
f=isinstance(g,Iterable)
print(f)#True


'''
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器只能往前不会后退


!!可以被next()函数调用并不断返回下一个值得对象称为迭代器:Iterator
'''

#可迭代的是否就是迭代器对象---不是
#列表是可迭代的,但是它不能放在next()里面  因此它不是迭代器
# list1=[1,2,3,4,5]
# print(next(list1))---列表是可迭代的但不是迭代器

#把列表(可迭代的)变成迭代器
list1=[1,2,3,4,5]
list1=iter(list1)
print(next(list1))#1
print(next(list1))#2


'''
生成器既是可迭代的又是迭代器
生成器与迭代器:
生成器取代列表推导式,节省空间
生成器是一种迭代器
'''