VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > python入门教程 >
  • python--高级语法 7

day12:

1、生成器(重点)

  • 生成器:python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。唯一的区别:生成器是我们自己用python代码构建的数据结构。迭代器都是提供的,或者转化得来的

1.获取生成器的三种方式:

  • 生成器函数。
  • 生成器表达式。
  • python内置函数或者模块提供。
    • (其实1,3两种本质上差不多,都是通过函数的形式生成,只不过1是自己写的生成器函数,3是python提供的生成器函数而已)

2.获取迭代器的方式:

  • python提供的,比如文件句柄
  • 通过 iter 转化的

3.生成器函数 获得生成器:

  • 将函数中的return换成yield,这样func就不是函数了,而是一个生成器函数
  • 读取生成器的内容是,一个next 对应一个yield
#函数
# def func():
#     print(111)
#     print(222)
#     return 3
#
# ret=func()
# print(ret)

#生成器
def func():
    print(111)
    print(222)
    yield 3
    a=1
    b=2
    c=a+b
    print(c)
    yield 4

ret=func()
print(ret)
print(next(ret))
print(next(ret))

#一个next 对应一个yield

<generator object func at 0x000002974F4E60A0>
111
222
3
3
4
Process finished with exit code 0

面试题:return 和 yield 的区别?

  • return:函数中只存在一个return结束函数,并且给函数的执行者返回值。
  • yield:只要函数中有yield那么它就是生成器函数而不是函数了。生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next。

练习题:吃包子

  • 需求:老男孩向楼下卖包子的老板订购了5000个包子.包子铺老板非常实在,一下就全部都做出来了 
def func():
    l1=[]
    for i in range(1,5001):
        l1.append(f'{i}号包子')
    return l1

ret=func()
print(ret)
  • 这样做没有问题,但是我们由于学生没有那么多,只吃了2000个左右,剩下的8000个,就只能占着一定的空间,放在一边了。如果包子铺老板效率够高,我吃一个包子,你做一个包子,那么这就不会占用太多空间存储了,完美。(用生成器做)
def eat_func():
    for i in range(1,5001):
        yield f'{i}号包子'

ret=eat_func()
for i in range(200):
    print(next(ret))

思考:这两者的区别:

第一种是直接把包子全部做出来,占用内存。

第二种是吃一个生产一个,非常的节省内存,而且还可以保留上次的位置。

4.yield from

  • 比如我yield 一个列表,我不想返回一个列表,想返回列表里的内容,就用yield from,将这个列表变成了迭代器返回
#yield from
def func():
    l1=[1,2,3,4,5]
    yield l1

ret=func()
print(next(ret))
#得到的是一个列表
#但是我不希望是一个列表  ----(1)yield from   (2)用*解包
#(1)yield from
def func():
    l1=[1,2,3,4,5]
    yield from l1
    #将l1这个列表变成了迭代器返回
ret=func()
print(next(ret))

# (2)用*解包
def func():
    l1=[1,2,3,4,5]
    return l1

ret=func()
print(*ret)

[1, 2, 3, 4, 5]
1
1 2 3 4 5

Process finished with exit code 0

2.列表推导式,生成器表达式

  • 列表推导式:用一行代码构建一个比较复杂有规律的列表

  • 列表推导式:

    • 循环模式:[变量(加工后的变量) for 变量 in iterable]
    • 筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]

1,列表推导式练习题:

#需求:创建一个有规律的列表,如1-10

#(1).常规方法:
l1=[]
for i in range(1,11):
    l1.append(i)
print(l1)

#(2).用列表推导式:
l2=[i for i in range(1,11)]
print(l2)

#用列表推导式(两种模式)
#1.循环模式
#需求1:将10以内所有整数的平方写入列表
l3=[i**2 for i in range(1,11)]
print(l3)

#需求2:将100以内所有偶数写入列表
l4=[i for i in range(2,101,2) ]
print(l4)

#需求3:从python1期到python100期写入列表
l5=[f'python{i}期' for i in range(1,101)]
print(l5)

#2.筛选模式  (在循环模式后面加上  if条件)

#需求1:将100以内所有偶数写入列表
l6=[i for i in range(1,101) if i%2 == 0]
print(l6)

#需求2:将30以内能被3整取的数写入列表
l7=[i for i in range(1,31) if i%3 ==0]
print(l7)

#需求3:过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
l8 = ['wusir', 'laonanhai', 'aa', 'b', 'taibai']
print([i.upper() for i in l8 if len(i)>3 ])

#需求4:找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]

#传统方法:
l9=[]
for i in names:
    for name in i:
        if name.count('e')==2:
            l9.append(name)
print(l9)

#列表推导式:筛选模式
l10=[name for i in names for name in i if name.count('e')==2]
print(l10)

2,生成器表达式

  • 生成器表达式和列表推导式的语法上一模一样,只是把[]换成()就行了。

    比如将十以内所有数的平方放到一个生成器表达式中

l11=(i for i in range(1,11))
print(l11)
print(next(l11))
print(next(l11))

<generator object <genexpr> at 0x00000264FE056048>
1
2

Process finished with exit code 0
  • 生成器表达式也可以进行筛选
# 获取1-100内能被3整除的数
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
    print(num)

3.生成器表达式和列表推导式区别:

  1. 列表推导式比较耗内存,所有数据一次性加载到内存。而.生成器表达式遵循迭代器协议,逐个产生元素。
  2. 得到的值不一样,列表推导式得到的是一个列表.生成器表达式获取的是一个生成器
  3. 列表推导式一目了然,生成器表达式只是一个内存地址

3,内置函数

  • 函数就是以功能为导向,一个函数封装一个功能,那么Python将一些常用的功能(比如len)给我们封装成了一个一个的函数,供我们使用
  • python 提供了68个内置函数
一带而过:
all()  any()  bytes() callable() chr() complex() divmod() eval() exec() format() frozenset() globals() hash() help() id() input() int()  iter() locals() next()  oct()  ord()  pow()    repr()  round()

重点讲解:
abs() enumerate() filter()  map() max()  min() open()  range() print()  len()  list()  dict() str()  float() reversed()  set()  sorted()  sum()    tuple()  type()  zip()  dir() 

未来会讲:
classmethod()  delattr() getattr() hasattr()  issubclass()  isinstance()  object() property()  setattr()  staticmethod()  super()

eval() ---掌握

  • 执行字符串类型的代码(外衣),并返回最终结果
#-----如将字符串类型转化为数字类型
s1='1+3'
print(s1)
print(type(s1))

print(eval(s1))
print(type(eval(s1)))

1+3
<class 'str'>
4
<class 'int'>

Process finished with exit code 0
#-----如将字符串类型转化为字典类型
s2='{"name":"mike"}'
print(s2,type(s2))
print(eval(s2),type(eval(s2)))

{"name":"mike"} <class 'str'>
{'name': 'mike'} <class 'dict'>

Process finished with exit code 0

exec()

  • 与eval几乎一样 ,执行字符串类型的代码
msg="""
list=[]
for i in range(10):
    list.append(i)
print(list)
"""

print(msg)
exec(msg)

#**************************************************************************
list=[]
for i in range(10):
    list.append(i)
print(list)

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

Process finished with exit code 0

hash()

  • hash:获取一个对象(可哈希对象:int,str,Bool,tuple)的哈希值。
  • 加密算法需要哈希值
print(hash('123456'))
4362549678203584146

Process finished with exit code 0
#使用python 进行 MD5加密接口测试:
import hashlib


password='123456'
obj=hashlib.md5(password.encode())
passwordmd5=obj.hexdigest()
print(passwordmd5)

e10adc3949ba59abbe56e057f20f883e

Process finished with exit code 0

help() ---掌握

  • help:函数用于查看函数或模块用途的详细说明。
print(help(str.split))

Help on method_descriptor:

split(...)
    S.split(sep=None, maxsplit=-1) -> list of strings
    
    Return a list of the words in S, using sep as the
    delimiter string.  If maxsplit is given, at most maxsplit
    splits are done. If sep is not specified or is None, any
    whitespace string is a separator and empty strings are
    removed from the result.

None

Process finished with exit code 0

callable() ---重点

  • callable:函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。
s1='12332312'
def func():
    pass

print(callable(s1))
print(callable(func))

False
True

Process finished with exit code 0

bytes() ---重点

  • 把字符串转换成bytes(字节)类型

    #bytes
    s1='太白'
    b=s1.encode('utf-8')
    print(b)
    
    #或者用bytes将字符串转换为字节
    b=bytes(s1,encoding='utf-8')
    print(b)
    
    # 将字节转换成字符串
    c= str(b,encoding='utf-8')
    print(c)
    太白
    
    b'\xe5\xa4\xaa\xe7\x99\xbd'
    b'\xe5\xa4\xaa\xe7\x99\xbd'
    
    Process finished with exit code 0
    

print() 屏幕输出

int():pass

str():pass

bool():pass

set(): pass

**list() **

  • 将一个可迭代对象转换成列表

    l1='qweqeqweqweqweaaddff'
    l2=list(l1)
    print(l2)
    
    ['q', 'w', 'e', 'q', 'e', 'q', 'w', 'e', 'q', 'w', 'e', 'q', 'w', 'e', 'a', 'a', 'd', 'd', 'f', 'f']
    
    Process finished with exit code 0
    

**tuple() **

将一个可迭代对象转换成元组

tu1 = tuple('abcd')
print(tu1)  
# ('a', 'b', 'c', 'd')

**dict() **

  • 通过相应的方式创建字典

    #dict
    #创建字典的方式
    #1.直接创建
    dic=dict([(1,'one'),(2,'two')])
    print(dic)
    
    #2.元组的解构
    dic=dict(one=1,twe=2)
    print(dic)
    
    #3.fromkeys
    #4.update
    #5.字典的推导式
    
    {1: 'one', 2: 'two'}
    {'one': 1, 'twe': 2}
    
    Process finished with exit code 0
    

**abs() **

  • 返回绝对值
i = -5
print(abs(i))  # 5

reversed()与reverse() ---重点

  • **reversed() ** 将一个序列翻转, 返回翻转序列的迭代器 ---

  • reverse() 对原列表进行倒序。翻转

    l1=[i for i in range(10)]
    print(l1)
    l1.reverse()  #  对原列表进行倒序。翻转
    print(l1)
    
    l2=[i for i in range(10)]
    print(l2)
    obj=reversed(l2)
    print(obj)
    print(next(obj))
    print(list(obj))
    
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    <list_reverseiterator object at 0x000002409D57A1D0>
    9
    [8, 7, 6, 5, 4, 3, 2, 1, 0]
    
    Process finished with exit code 0
    

zip() 拉链方法 ---重点

  • 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回

    lst1 = [1,2,3]
    lst2 = ['a','b','c','d']
    lst3 = (11,12,13,14,15)
    
    obj=zip(lst1,lst2,lst3)
    print(obj)
    
    for i in zip(lst1,lst2,lst3):
        print(i)
        
    <zip object at 0x00000244D015A648>  
    (1, 'a', 11)
    (2, 'b', 12)
    (3, 'c', 13)
    
    Process finished with exit code 0
    
  • 以下方法最最要:

    min( ),max()

    l1=[33,2,1,54,7,-1,-9]
    print(min(l1))
    
    #以绝对值的方式取最小值
    #(1)第一种方法
    l2=[]
    def func(a):
        return abs(a)
    
    for i in l1:
        l2.append(func(i))
    print(l2)
    print(min(l2))
    
    #(2)第二种方法
    
    l1=[33,2,1,54,7,-1,-9]
    #print(min(l1,key=abs))
    
    def abss(a):
        return abs(a)
    '''
            第一次:a = 33  以绝对值取最小值  33
            第二次:a = 2  以绝对值取最小值  2
            第三次:a = 3  以绝对值取最小值  2
            ......
            第六次:a = -1   以绝对值取最小值  1
    '''
    print(min(l1,key=abss))
    #凡是可以加key的:它会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中
    
    1
    
    Process finished with exit code 0
    

    练习题:

    dic={'a':3,
         'b':2,
         'c':1}
    #求出值最小的键值
    print(min(dic))    #a  min默认会按照字典的键去比较大小。
    #
    # def func(i):
    #     return dic[i]
    # print(min(dic,key=func))
    
    #优化下函数--使用匿名函数
    print(min(dic,key=lambda i:dic[i]))
    
    a
    c
    
    Process finished with exit code 0
    

    sorted() 排序函数

    • [ˈsɔːtɪd] sou 太d

    • 排序函数, 不是对原列表进行排序,返回的是一个新列表,默认从低到高

      l1=[22,33,1,2,8,7,6,5]
      l2=sorted(l1)
      print(l1)
      print(l2)
      
      [22, 33, 1, 2, 8, 7, 6, 5]
      [1, 2, 5, 6, 7, 8, 22, 33]
      
      Process finished with exit code 0
      
      l2=[('太白',18),('alex',73),('wu',35),('口天吴',41)]
      print(sorted(l2))
      
      #想按照成绩去排序
      print(sorted(l2,key=lambda x:x[1]))  #返回的是一个列表 ,默认从低到高
      print(sorted(l2,key=lambda x:x[1],reverse=True))    #设置从高到底
      
      [('alex', 73), ('wu', 35), ('口天吴', 41), ('太白', 18)]
      [('太白', 18), ('wu', 35), ('口天吴', 41), ('alex', 73)]
      [('alex', 73), ('口天吴', 41), ('wu', 35), ('太白', 18)]
      
      Process finished with exit code 0
      

    filter()

    • 筛选过滤(类似于列表推导式的帅选模式) 返回的是迭代器

    • 语法: filter(function,iterable)
      
      function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据
      
      iterable:可迭代对象
      
      # filter 筛选过滤
      l1=[2,3,4,1,6,7,8]
      #把小于3的元素剔除
      #(1)列表推导式筛选
      print([i for i in l1 if i>3])   #返回的是列表
      
      #(2)使用 filter
      ret=filter(lambda x:x>3,l1)    #返回的是迭代器
      print(ret)
      print(list(ret))
      
      [4, 6, 7, 8]
      <filter object at 0x00000181997B9828>
      [4, 6, 7, 8]
      
      Process finished with exit code 0
      

    map()

    • 会根据提供的函数对指定的序列做映射。(相当于列表推导式的循环模式)
    • 通俗地讲就是以参数序列中的每个元素分别调用参数中的函数(func()),把每次调用后返回的结果保存到返回值中
    映射函数
    
    语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function
    >>> def square(x):
    >>>     return x ** 2
    >>> map(square,[1,2,3,4,5])
    <map at 0xbd26f28>
    >>> list(map(square,[1,2,3,4,5]))
    [1, 4, 9, 16, 25]
    
    #map()
    #计算列表中每个元素的平方,返回新列表
    lst = [1,2,3,4,5]
    
    #(1)列表推导式的循环模式
    print([i**2 for i in lst])
    
    #(2)map()
    ret=map(lambda x:x**2,lst)
    print(ret)
    print(list(ret))
    
    [1, 4, 9, 16, 25]
    <map object at 0x000001DF48669080>
    [1, 4, 9, 16, 25]
    
    Process finished with exit code 0
    

    4、匿名函数

    语法:

    函数名 = lambda 参数:返回值
    fun1=lambda a,b:a+b
    
    1. 此函数不是没有名字,他是有名字的,他的名字就是你给其设置的变量,比如func.
    2. lambda 是定义匿名函数的关键字,相当于函数的def.
    3. lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。
    4. 返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。
    5. 匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据
    def  func(a,b):
        return a+b
    
    #构建匿名函数
    fun1=lambda a,b:a+b
    print(fun1(1,2))
    

    接下来做几个匿名函数的小题:

    写匿名函数:接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。

    fun2=lambda a:(a[0],a[2])
    print(fun2([22,33,44,55]))
    (22, 44)
    
    Process finished with exit code 0
    

    出处:https://www.cnblogs.com/wushaofan/p/17156647.html
     


相关教程