zoukankan      html  css  js  c++  java
  • day05_雷神_函数进阶

    day05


    1、迭代器

    1.1可迭代对象

    str,list,tuple,dict,set,range,文件句柄 等都是可迭代对象

    第一种方法:在该对象中,含有__iter__方法的就是可迭代对象,遵循可迭代协议。

    print(dir(str)) 
    dir() 打印出str对象的所有方法。
    
    print('__iter__' in dir(list))
    返回值: True 说明是可迭代对象
    

    第二种方法: isinstance("123",Iterable)

    from collections import Iterable  (需要import Iterable)
    a = isinstance("[1,2,3]", Iterable)
    print(a)
    

    1.2迭代器

    内部含有__iter__ 且含有__next__方法的对象就是迭代器,遵循迭代器协议。

    将可迭代对象转换为迭代器(两种方法)

    s1 = "abc"
    obj_s1 = iter(s1)  #方法一
    obj_s1 = s1.__iter__()  #方法二
    print(obj_s1)
    结果:<str_iterator object at 0x000002370C657390>
    
    迭代器只能通过__next__方法来读取值:
    print(obj_s1.__next__())  # a
    print(obj_s1.__next__())  # b
    print(obj_s1.__next__())  # c
    print(obj_s1.__next__())  # 报错:StopIteration
    

    判断是否是迭代器的方法一:

    s1 = "asd"
    print('__iter__' in dir(s1))  #True
    print('__next__' in dir(s1))  #False
    
    obj_s1 = iter(s1)
    print('__iter__' in dir(obj_s1))  #True
    print('__next__' in dir(obj_s1))  #True
    

    方法二:

    s1 = "asd"
    obj_s1 = iter(s1)
    print(isinstance(s1,Iterator))    #False
    print(isinstance(obj_s1,Iterator))    #True
    

    迭代器的好处

    节省内存
    惰性机制
    单向不可逆
    

    1.3生成器

    生成器的本质就是迭代器,他是自定义的迭代器(用Python写的)。

    1. 函数的方式构建一个生成器:
    示例1:
    def func1():
        print(111)
        yield 222
        print(333)
        print(444)
    obj_1 = func1()   # g_obj = func1()  # 生成器对象
    #  凡是函数中见到yield 他就是生成器
    print(obj_1)
    
    print(obj_1.__next__())   # 111, 222  一个next对应一个yield,一一对应
    print(obj_1.__next__())   # 报错StopIteration 
    
    示例2:
    def cloth():
    for i in range(1,5001):
        yield '衣服%s' %i
    g_obj = cloth()  #生成器对象
    print(g_obj)	#<generator object cloth at 0x0000020ADFBCDE08>
    for i in range(1,51):
        print(g_obj.__next__())  # 先来50套
    for i in range(1,101):
        print(g_obj.__next__())  # 再加100套,从50到了150套,因为迭代器单向不可逆
    

    send

    send和next都是对生成器取值,每一个都要对应一个yield,send 会给上一个yield 发送一个值。

    send 不能用在第一次取值。最后一个yield 不能得到值

    def func1():
        count = yield 666
        print(count)
        yield 777
        yield 888
    g_obj = func1()
    print(g_obj.__next__())
    # print(g_obj.__next__())
    # 666
    # None
    # 777
    print(g_obj.send('taibai'))  
    # 666
    # taibai
    # 777
    # print(g_obj.send('alex'))  # 相当于给yield 777 整体赋值为"alex",只是没有打印
    

    2、列表推导式(生成器表达式)

    遍历模式 l = [ i for i in range(1,11)]

    [ (结果需要的变量形式)变量 for 变量 in iterable ]

    [变量(加工后的变量) for 变量 in iterable] 遍历模式

    l2 = ['python%s期' % i for i in range(1,23)]
    print(l2)
    

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

    l2 = [i for i in range(1,31) if i % 3 == 0]
    print(l2)
    l2_obj = (i for i in range(1,31) if i % 3 == 0)  #将[]换成()就是生成器表达式了。
    print(l2_obj)
    print(l2_obj.__next__())
    print(l2_obj.__next__()) 
    
    li = ["a","c",'houbinglei','alex']
    l = [i.upper() for i in li if len(i)>=3 ]
    print(l)
    

    区别

    # 列表推导式:简单,一行搞定。
    # 特别复杂的数据列表推导式无法实现,只能用其他方式实现。
    # 列表推导式不能排错。
    # 列表推导式与生成器表达式区别
    # 1 ,列推直观能看出,但是占内存
    # 2,生成器表达式不易看出,但是节省内存。
    
    示例:-
    x = {
        'name':'alex',
        'Values':[{'timestamp':1517991992.94,
             'values':100,},
            {'timestamp': 1517992000.94,
            'values': 200,},
            {'timestamp': 1517992014.94,
             'values': 300,},
            {'timestamp': 1517992744.94,
             'values': 350},
            {'timestamp': 1517992800.94,
             'values': 280}
    		],}
    
    li = [[i['timestamp'],i['values']] for i in x['Values'] ]
    print(li)
    关键:从要的数据类型分析出规律。
    

    字典推导式

    将一个字典的key和value对调
    mcase = {'a': 10, 'b': 34}
    mcase_frequency = {mcase[k]: k for k in mcase}
    print(mcase_frequency)
    

    3、 内置函数

    见过的

    '''
    len()
    print()
    input()
    range()
    list()  
    tuple()
    str()
    int()
    set()。。。。。
    '''
    

    dict()

    field = ["id","name","age","phone","job"]
    def yie_file():
        with open("yuan_gong",encoding="utf-8") as f:
            for line in f:
                yield line.strip().split()
    li = []
    for i in yie_file():
        dic = dict(zip(field,i))
        if int(dic['age']) > 25:
            print(dic)
        else:
            li.append(dic)
    print(li)
    结果:
    {'id': '4', 'name': 'houbinglei', 'age': '27', 'phone': '17718351482', 'job': 'IT'}
    [{'id': '2', 'name': 'Egon', 'age': '23', 'phone': '13304320533', 'job': 'Tearcher'}, {'id': '3', 'name': 'nezha', 'age': '25', 'phone': '1333235322', 'job': 'IT'}]
    

    1.1. 作用域相关

    locals :函数会以字典的类型返回当前位置的全部局部变量。
    
    globals:函数以字典的类型返回全部全局变量。
    

    1.2 其他相关
    1.2.1 字符串类型代码的执行,eval,exec

    	eval:去除字符串两边的引号,输出里边的结果,并返回最终结果。执行字符串表达式。
    print(eval('1 + 2 +3'))
    print(eval("{'name':'alex'}"),type(eval("{'name':'alex'}")))
    
      exec:也是去除两边的引号,但是不返回结果,执行代码,执行文件。
    s1 = '''
    for i in range(5):
        print(i)
    '''
    print(exec(s1))
    

    1.2.2 输入输出相关

    ''' 源码分析
    def print(self, *args, sep=' ', end='
    ', file=None): # known special case of print
        """
        print(value, ..., sep=' ', end='
    ', file=sys.stdout, flush=False)
        file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
        sep:   打印多个值之间的分隔符,默认为空格
        end:   每一次打印的结尾,默认为换行符
        flush: 立即把内容输出到流文件,不作缓存
        """
    '''
    
    print(111,222,333,sep='*')  # 111*222*333
    
    print(111,end='')
    print(222)  #两行的结果 111222
    
    f = open('log','w',encoding='utf-8')
    print('写入文件',file=f,flush=True)
    

    1.2.3 内存相关

    hash:获取一个对象(可哈希对象:int,str,Bool,tuple)的哈希值。

    id:用于获取对象的内存地址。

    print(hash('arg'))
    print(id('abc'))  # 2033192957072
    

    1.2.3文件操作相关

      open:函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

    1.2.4模块相关__import__ 

      __import__:函数用于动态加载类和函数 。

    1.2.5帮助

      help:函数用于查看函数或模块用途的详细说明。

    1.2.6 调用相关

    callable:函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。

    name = 'alex'
    
    def func1():
        print(111)
    print(callable(name))  False
    print(callable(func1))  True
    函数名加括号就能用,再面向对象比较有用。
    

    1.2.7查看内置属性

    dir:函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。

    dir()   #  获得当前模块的属性列表
    

    1.3 迭代器生成器相关

    # 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    # 循环:
    while True:
        try:
            # 获得下一个值:
            x = next(it)
            print(x)
        except StopIteration:
            # 遇到StopIteration就退出循环
            break
    
    iter:函数用来生成迭代器(讲一个可迭代对象,生成迭代器)。
    from collections import Iterable
    from collections import Iterator
    l = [1,2,3]
    print(isinstance(l,Iterable))  # True
    print(isinstance(l,Iterator))  # False
    
    l1 = iter(l)
    print(isinstance(l1,Iterable))  # True
    print(isinstance(l1,Iterator))  # True
    

    1.4 基础数据类型相关

    1.4.1数字相关(14)

    数据类型(4):

        bool :用于将给定参数转换为布尔类型,如果没有参数,返回 False。

        int:函数用于将一个字符串或数字转换为整型。

        float:函数用于将整数和字符串转换成浮点数。

    进制转换(3):

        bin:将十进制转换成二进制并返回。

        oct:将十进制转化成八进制字符串并返回。

        hex:将十进制转化成十六进制字符串并返回。

    数学运算(7):

    abs:函数返回数字的绝对值。

    print(abs(-5))  # 5
    

    divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)。

    print(divmod(7,2))  # (3, 1)
    

    round:保留浮点数的小数位数,默认保留整数。

    print(round(7/3,2))  # 2.33
    print(round(7/3))  # 2
    

    pow:求xy次幂。(三个参数为xy的结果对z取余)

    print(pow(2,3))  # 两个参数为2**3次幂
    print(pow(2,3,3))  # 三个参数为2**3次幂,对3取余。
    

    sum:对可迭代对象进行求和计算(可设置初始值)。

    l1 = [i for i in range(100)]
    print(sum(l1))
    print(sum(l1,100)) # 初始值是100 ,最后算完再加上100
    

    min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。

    print(min([1,2,3]))  # 返回此序列最小值
    
    ret = min([1,2,-5,],key=abs)  # 按照绝对值的大小,返回此序列最小值
    print(ret)
    
    dic = {'a':3,'b':2,'c':1}
    print(min(dic,key=lambda x:dic[x]))
    
    ###这里可迭代对象如果是字典,x默认是每个字典的key值;
    ###如果可迭代对象是s = [[3,2],[7,4],[1,6]]这种,x会默认接收每个元素的第一个值。
    

    max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)

    dic = {'a':3,'b':2,'c':1}
    print(max(dic,key=lambda x:dic[x]))
    # x为dic的key,lambda的返回值(即dic的值进行比较)返回最大的值对应的键,x默认接收字典的key。
    

    1.4.2和数据结构相关(24)

    列表和元祖(2)

        list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素)。

        tuple:将一个可迭代对象转化成元祖(如果是字典,默认将key作为元祖的元素)。

    l = list((1,2,3))
    print(l)
    
    l = list({1,2,3})
    print(l)
    
    l = list({'k1':1,'k2':2})
    print(l)
    

    相关内置函数(2)

        reversed:将一个序列翻转,并返回此翻转序列的迭代器。

    l3 = [2, 3, 9, 8, 7, 4]
    l3.reverse()
    print(l3)
    l_obj = reversed(l3)
    print(l_obj)   #<list_reverseiterator object at 0x0000025DDEB47908>
    for i in l_obj:
        print(i)
    print(sum(l_obj))  # 33  sum直接求和迭代器。
    print(sum(l3))		# 33  sum 本身就可以求和可迭代对象。
    

        slice:构造一个切片对象,用于列表的切片。

    字符串相关(9)

        str:将数据转化成字符串。

        format:与具体数据相关,用于计算各种小数,精算等。

    print(format('test', '<30'))    左对齐
    print(format('test', '>20'))	右对齐
    print(format('test', '^20'))	剧中
    

    bytes:用于不同编码之间的转化。相当于encode

    s1 = "abc"
    print(bytes(s1,encoding="utf-8"))  
    print(s1.encode("utf-8"))
    
    两种方法将str转换为bytes数据类型;解码只能用decode
    

    ord:输入字符找该字符编码的位置   unicode

    print(ord('a'))  # 97
    print(ord('中'))   #20013
    

    chr:输入位置数字找出其对应的字符

    print(chr(97))
    print(chr(20013))
    

    ascii:是ascii码中的返回该值,不是就返回/u...

    print(ascii('a'))
    print(ascii('中'))
    

    repr:返回一个对象的string形式(原形毕露)。

    print(repr('{"name":"alex"}'),type(repr('{"name":"alex"}')))  #'{"name":"alex"}' <class 'str'>
    print('{"name":"alex"}')  
    print('python%s期' % '22')  # python22期
    print('python%r期' % '22')   # python'22'期
    

    数据集合(3)

    dict:创建一个字典。

    set:创建一个集合。

    frozenset:返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。

    ***  sorted:对所有可迭代的对象进行排序操作。返回列表。

    L = [('a', 1), ('c', 3), ('d', 4),('b', 2), ]
    sorted(L, key=lambda x:x[1])               # 利用key
    [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
    
    x:自动获取可迭代对象的每一个值,并默认按照每个元素的第一个值排序。
    字典默认是对Key排序。
    dic = {"c":1,"a":3,"b":9}
    print(sorted(dic))   #['a', 'b', 'c']
     
     
    students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
    sorted(students, key=lambda s: s[2])            # 按年龄排序
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
     
    sorted(students, key=lambda s: s[2], reverse=True)    # 按降序
    [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
    

    *** enumerate:枚举,返回一个枚举对象。

    dic = {"c":1,"a":3,"b":9}
    for i in enumerate(dic):
        print(i)
    结果:
    (0, 'c')
    (1, 'a')
    (2, 'b')
    
    for index,key in enumerate(dic):
        print("序号{}的值是{}".format(index,key))
    结果:
    序号0的值是c
    序号1的值是a
    序号2的值是b
    

    all:可迭代对象中,全都是True才是True

    any:可迭代对象中,有一个True 就是True

    l1 = [1, 'alex', 3]
    l2 = [0, '', False,(), 1]
    print(all(l1))
    print(any(l2))
    

    ***zip 拉链方法,函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,并没有返回列表,需要用for循环读取这个迭代器。

    l1 = [1,2,3,]
    l2 = ['a','b','c',5]
    l3 = ('*','**',(1,2,3),666,777)
    for i in zip(l1, l2, l3):
        print(i)
    
    结果:
    (1, 'a', '*')
    (2, 'b', '**')
    (3, 'c', (1, 2, 3))
    

    ***map:会根据提供的函数对指定序列做映射。返回的是迭代器,类似于列表推导式的遍历模式。

    >>>def square(x) :            # 计算平方数
    ...     return x ** 2
    ... 
    >>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
    [1, 4, 9, 16, 25]
    <map object at 0x00000268A1747908>
    >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
    [1, 4, 9, 16, 25]
     
    # 提供了两个列表,对相同位置的列表数据进行相加
    >>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
    [3, 7, 11, 15, 19]
    

     filter:过滤·。

    类似于[i for i in range(1,8) if i % 2 == 0 ]
    def func(x):return x%2 == 0
    ret = filter(func,[1,2,3,4,5,6,7])
    print(ret)   #<filter object at 0x0000018EE48679B0>
    for i in ret:
        print(i)
    
    	portfolio = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}]
    
    ret = filter(lambda x:x['price'] > 100, portfolio )
    print(ret)  # <filter object at 0x0000021B7F357E48>
    for i in ret:
        print(i)
    

    min,max,sorted,map,filter

    返回结果:

    filter: ret = filter(lambda x:x['price'] > 100, portfolio )
    			print(ret)
    			<filter object at 0x0000021B7F357E48>  返回迭代器
    
    sorted: students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
    			sorted(students, key=lambda s: s[2])            # 按年龄排序
    			[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]  返回列表
    
    zip: ret = zip(l_new,l2,tu)
    			print(ret) <zip object at 0x00000292D35BE5C8> 返回迭代器
    		for i in a:
    			print(i) 
    			(3, 'oldboy', '**')   返回元祖
    
    map:  ret = map(lambda x:x['shares'] * x['price'], portfolio)  # 字典的两个值相乘。
    		print(ret)  <map object at 0x000002CFC04E7EB8>  返回迭代器
    		li = []
    		for i in ret:
    		    li.append(i)
    		print(li)
    
    list: l=[{'name':'alex'},{'name':'y'}]
    		ret = map(lambda x:x['name']+'SB', l)  ret是迭代器。
    		print(list(ret))  	list()将可迭代对象转换为列表,同样可以直接转换迭代器。
    		结果: ['alexSB', 'ySB']
    

    4 匿名函数

    def func(x,y): return x + y
    	print(func(3,4))
    func1 = lambda x,y: x + y
    	print(func1(3,4))
    #def func1(x): return x**2
    res = map(lambda x: x**2,[1,5,7,4,8])
    for i in res:
        print(i)
    

    5.函数的有用信息

    from functools import wraps
    
    def logger(f):
        @wraps(f)
        def inner(*args, **kwargs):
            """
            :param args: 函数名,密码
            :param kwargs: 备用
            :return:  True
            """
            ret = f(*args, **kwargs)
            return ret
        return inner
    
    @logger
    def login(username,password):
        """
        此函数是完成登录功能的函数,需要用户名,和密码两个参数,返回True 登陆成功
        :return:  True
        """
        print(666)
        return True
    login(1,2)  #inner()
    # # login('alex', 123)
    print(login.__doc__)
    print(login.__name__)
    
    遇到装饰器的时候,要还是打印原函数的有用信息,需要from functools import wraps。并且正在inner函数上添加@wraps(f)。
    

    6. 装饰器的升级

    带参数的装饰器

    1,将@ 与函数分开@ timmerout(flag) 返回了timmer

    2,将@timmer结合

    def timmerout(flag1):  # flag1 =flag
        def timmer(f):
            def inner(*args,**kwargs):
                if flag1:
    				print(flag1)
                    start_time = time.time()
                    ret = f(*args,**kwargs)
                    end_time = time.time()
                    print('此函数的执行效率%s' % (end_time - start_time))
                    return ret
                else:
                    ret = f(*args, **kwargs)
                    return ret
            return inner
        return timmer
    
    @timmerout('京东')  # 1,将@ 与函数分开@     timmerout(flag)  返回了timmer 2,将@timmer结合。
    def JDshop():
        time.sleep(0.3)
        print('非常复杂......')
        return 666
    
    @timmerout('京东')
    def JD():
        time.sleep(0.3)
        print('非常复杂......')
        return 666
    
    
    @timmerout('淘宝')
    def taobao():
        time.sleep(0.1)
        print('非常复杂......')
        return 666
    
    @timmerout('淘宝')
    def taobaoshop():
        time.sleep(0.1)
        print('非常复杂......')
        return 666
    
    taobaoshop()
    结果 :
    淘宝
    非常复杂......
    此函数的执行效率0.10024571418762207
    

    多个装饰器装饰一个函数

    @wrapper2  # f = warpper2(f)  里面的f是inner1 外面的f是inner2
    @wrapper1  # f = warpper1(f)  里面的f函数名 外面的f 是inner1
    def f():
        print('in f')  # 3
    
    f()  # inner2()
    
    wrapper2 ,before func
    wrapper1 ,before func
    in f
    wrapper1 ,after func
    wrapper2 ,after func
    My name is 侯冰雷 ~~欢迎转载 ~~欢迎关注 ~~欢迎留言
  • 相关阅读:
    C# 編譯錯誤 CS0016 解決方案
    Javascript 日期
    Javascript Url处理
    Linq中in用法
    oracle中的排名函数用法
    webservices [WebServiceBinding(ConformsTo = WsiProfiles.None)]
    C#中的多态
    C# Math类简介 (转)
    客服工单任务系统发展简史 商商
    jQuery LigerUI 使用教程表格篇(2) 服务器数据交互
  • 原文地址:https://www.cnblogs.com/houbinglei/p/9268826.html
Copyright © 2011-2022 走看看