zoukankan      html  css  js  c++  java
  • DAY4-函数进阶

    目录:

    一、迭代器

    一、迭代的概念

    #迭代器即迭代的工具,那什么是迭代呢?
    #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
    while True: #只是单纯地重复,因而不是迭代
        print('===>') 
        
    l=[1,2,3]
    count=0
    while count < len(l): #迭代
        print(l[count])
        count+=1

    二 为何要有迭代器?什么是可迭代对象?什么是迭代器对象?

    #1、为何要有迭代器?
    对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
    
    #2、什么是可迭代对象?
    可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下
    'hello'.__iter__
    (1,2,3).__iter__
    [1,2,3].__iter__
    {'a':1}.__iter__
    {'a','b'}.__iter__
    open('a.txt').__iter__
    
    #3、什么是迭代器对象?
    可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
    而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象
    
    文件类型是迭代器对象
    open('a.txt').__iter__()
    open('a.txt').__next__()
    
    
    #4、注意:
    迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
    调用obj.__iter__()方法,得到的是迭代器对象(对于迭代器对象,执行__iter__得到的仍然是它本身)

    三、迭代器对象的使用

    dic={'a':1,'b':2,'c':3}
    iter_dic=dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
    iter_dic.__iter__() is iter_dic #True
    
    print(iter_dic.__next__()) #等同于next(iter_dic)
    print(iter_dic.__next__()) #等同于next(iter_dic)
    print(iter_dic.__next__()) #等同于next(iter_dic)
    # print(iter_dic.__next__()) #抛出异常StopIteration,或者说结束标志
    
    #有了迭代器,我们就可以不依赖索引迭代取值了
    #迭代对象值取完了,会报异常退出,可使用try..except避免退出程序
    iter_dic=dic.__iter__()
    while 1:
        try:
            k=next(iter_dic)
            print(dic[k])
        except StopIteration:
            break
            
    #这么写太丑陋了,需要我们自己捕捉异常,控制next,python这么牛逼,能不能帮我解决呢?能,请看for循环

     四、for循环

    #基于for循环,我们可以完全不再依赖索引去取值了
    dic={'a':1,'b':2,'c':3}
    for k in dic:
        print(dic[k])
    
    #for循环的工作原理
    #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
    #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    #3: 重复过程2,直到捕捉到异常StopIteration,结束循环

    五、迭代器的优缺点

    #优点:
      - 提供一种统一的、不依赖于索引的迭代方式
      - 惰性计算,节省内存
    #缺点:
      - 无法获取长度(只有在next完毕才知道到底有几个值)
      - 一次性的,只能往后走,不能往前退

    二、生成器

    一、什么是生成器

    #只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
    
    def func():
        print('====>first')
        yield 1
        print('====>second')
        yield 2
        print('====>third')
        yield 3
        print('====>end')
    
    g=func()
    print(g) #<generator object func at 0x0000000002184360> 

    二、生成器就是迭代器

    g.__iter__
    g.__next__
    #2、所以生成器就是迭代器,因此可以这么取值
    res=next(g)
    print(res)
    yield的功能:
    1、yield为我们提供了一种自定义迭代器对象的方法
    2、yield与return的区别
      1:yield可以返回多次值   
      2:函数暂停与再继续的状态是由yield帮我们保存的

    三、练习

    1、自定义函数模拟range(1,7,2)

    2、模拟管道,实现功能:tail -f access.log | grep '404'

    #题目一:
    def my_range(start,stop,step=1):
        while start < stop:
            yield start
            start+=step
    
    #执行函数得到生成器,本质就是迭代器
    obj=my_range(1,7,2) #1  3  5
    print(next(obj))
    print(next(obj))
    print(next(obj))
    print(next(obj)) #StopIteration
    
    #应用于for循环
    for i in my_range(1,7,2):
        print(i)
    
    #题目二
    import time
    def tail(filepath):
        with open(filepath,'rb') as f:
            f.seek(0,2)
            while True:
                line=f.readline()
                if line:
                    yield line
                else:
                    time.sleep(0.2)
    
    def grep(pattern,lines):
        for line in lines:
            line=line.decode('utf-8')
            if pattern in line:
                yield line
    
    for line in grep('404',tail('access.log')):
        print(line,end='')
    
    #测试
    with open('access.log','a',encoding='utf-8') as f:
        f.write('出错啦404
    ')
    复制代码
    View Code

    四、协程函数

    #yield关键字的另外一种使用形式:表达式形式的yield
    def eater(name):
        print('%s 准备开始吃饭啦' %name)
        food_list=[]
        while True:
            food=yield food_list
            print('%s 吃了 %s' % (name,food))
            food_list.append(food)
    
    g=eater('egon')
    g.send(None) #对于表达式形式的yield,在使用时,第一次必须传None,g.send(None)等同于next(g),先将前面的代码执行,暂停在yield处,将yield后面值返回,food赋值先不操作。
    g.send('蒸羊羔') #然后e.send:1 从暂停的位置将值传给yield,food赋值  2、然后与next一样
    g.send('蒸鹿茸')
    g.send('蒸熊掌')
    g.send('烧素鸭')
    g.close()
    g.send('烧素鹅')
    g.send('烧鹿尾')
    #g.close()之后将无法在send传值

    五 练习
    1、编写装饰器,实现初始化协程函数的功能

    2、实现功能:grep  -rl  'python'  /etc

    #题目一:
    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    @init
    def eater(name):
        print('%s 准备开始吃饭啦' %name)
        food_list=[]
        while True:
            food=yield food_list
            print('%s 吃了 %s' % (name,food))
            food_list.append(food)
    
    g=eater('egon')
    g.send('蒸羊羔')
    
    #题目二:
    #注意:target.send(...)在拿到target的返回值后才算执行结束
    import os
    def init(func):
        def wrapper(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return wrapper
    
    @init
    def search(target):
        while True:
            filepath=yield
            g=os.walk(filepath)
            for dirname,_,files in g:
                for file in files:
                    abs_path=r'%s\%s' %(dirname,file)
                    target.send(abs_path)
    @init
    def opener(target):
        while True:
            abs_path=yield
            with open(abs_path,'rb') as f:
                target.send((f,abs_path))
    @init
    def cat(target):
        while True:
            f,abs_path=yield
            for line in f:
                res=target.send((line,abs_path))
                if res:
                    break
    @init
    def grep(pattern,target):
        tag=False
        while True:
            line,abs_path=yield tag
            tag=False
            if pattern.encode('utf-8') in line:
                target.send(abs_path)
                tag=True
    @init
    def printer():
        while True:
            abs_path=yield
            print(abs_path)
    
    
    g=search(opener(cat(grep('你好',printer()))))
    # g.send(r'E:CMSaaadb')
    g=search(opener(cat(grep('python',printer()))))
    g.send(r'E:CMSaaadb')
    os.walk 

    六、yield总结

    #1、把函数做成迭代器
    #2、对比return,可以返回多次值,可以挂起/保存函数的运行状态

    三、面向过程编程

    #1、首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序
    
    #2、定义
    面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么
    
    基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式
    
    #3、优点:复杂的问题流程化,进而简单化
    
    #4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身
    
    #5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd
    
    #6、举例
    流水线1:
    用户输入用户名、密码--->用户验证--->欢迎界面
    
    流水线2:
    用户输入sql--->sql解析--->执行功能

     ps:函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,面向过程的思路就是,把程序的执行当做一串首尾相连的功能,该功能可以是函数的形式,然后一个函数吃,拉出的东西给另外一个函数吃,另外一个函数吃了再继续拉给下一个函数吃。。。

    四、三元表达式、列表推导式、生成器表达式

    一、三元表达式

    name=input('姓名>>: ')
    res='SB' if name == 'alex' else 'NB'
    print(res)

    二、列表推导式

    #1、示例
    egg_list=[]
    for i in range(10):
        egg_list.append('鸡蛋%s' %i)
    
    egg_list=['鸡蛋%s' %i for i in range(10)]
    
    #2、语法
    [expression for item1 in iterable1 if condition1
    for item2 in iterable2 if condition2
    ...
    for itemN in iterableN if conditionN
    ]
    类似于
    res=[]
    for item1 in iterable1:
        if condition1:
            for item2 in iterable2:
                if condition2
                    ...
                    for itemN in iterableN:
                        if conditionN:
                            res.append(expression)
    
    #3、优点:方便,改变了编程习惯,可称之为声明式编程

    三、生成器表达式

    #1、把列表推导式的[]换成()就是生成器表达式
    
    #2、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
    >>> chicken=('鸡蛋%s' %i for i in range(5))
    >>> chicken
    <generator object <genexpr> at 0x10143f200>
    >>> next(chicken)
    '鸡蛋0'
    >>> list(chicken) #因chicken可迭代,因而可以转成列表
    ['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',]
    
    #3、优点:省内存,一次只产生一个值在内存中

    四、声明式编程练习

    1、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写

    2、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度

    3、求文件a.txt中最长的行的长度(长度按字符个数算,需要使用max函数)

    4、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?(需要使用sum函数)

    5、思考题

    with open('a.txt') as f:
        g=(len(line) for line in f)
    print(sum(g)) #为何报错?

    6、文件shopping.txt内容如下

    mac,20000,3
    lenovo,3000,10
    tesla,1000000,10
    chicken,200,1

    求总共花了多少钱?

    打印出所有商品的信息,格式为[{'name':'xxx','price':333,'count':3},...]

    求单价大于10000的商品信息,格式同上

    #题目一
    names=['egon','alex_sb','wupeiqi','yuanhao']
    names=[name.upper() for name in names]
    
    #题目二
    names=['egon','alex_sb','wupeiqi','yuanhao']
    names=[len(name) for name in names if not name.endswith('sb')]
    
    #题目三
    with open('a.txt',encoding='utf-8') as f:
        print(max(len(line) for line in f))
    
    #题目四
    with open('a.txt', encoding='utf-8') as f:
        print(sum(len(line) for line in f))
        print(sum(len(line) for line in f)) #求包换换行符在内的文件所有的字符数,为何得到的值为0?
        print(sum(len(line) for line in f)) #求包换换行符在内的文件所有的字符数,为何得到的值为0?
    
    #题目五(略)
    
    #题目六:每次必须重新打开文件或seek到文件开头,因为迭代完一次就结束了
    with open('a.txt',encoding='utf-8') as f:
        info=[line.split() for line in f]
        cost=sum(float(unit_price)*int(count) for _,unit_price,count in info)
        print(cost)
    
    
    with open('a.txt',encoding='utf-8') as f:
        info=[{
            'name': line.split()[0],
            'price': float(line.split()[1]),
            'count': int(line.split()[2]),
        } for line in f]
        print(info)
    
    
    with open('a.txt',encoding='utf-8') as f:
        info=[{
            'name': line.split()[0],
            'price': float(line.split()[1]),
            'count': int(line.split()[2]),
        } for line in f if float(line.split()[1]) > 10000]
        print(info)
    View Code

    五、第归与二分法

    一、递归调用的定义

    #递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用

    二、递归分为两个阶段:递推、回溯

    #图解。。。
    # salary(5)=salary(4)+300
    # salary(4)=salary(3)+300
    # salary(3)=salary(2)+300
    # salary(2)=salary(1)+300
    # salary(1)=100
    #
    # salary(n)=salary(n-1)+300     n>1
    # salary(1) =100                n=1
    
    def salary(n):
        if n == 1:
            return 100
        return salary(n-1)+300
    
    print(salary(5))

    三、python中递归的效率低而且没有尾递归优化

    #python中的递归
    python中的递归效率低,需要在进入下一次递归时保留当前的状态,在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
    但是python又没有尾递归,且对递归层级做了限制
    
    #总结递归的使用:
    1. 必须有一个明确的结束条件
    
    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
    
    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

    四、可以修改递归最大深度

    import sys
    sys.getrecursionlimit() #查看最大深度
    sys.setrecursionlimit(2000) #修改最大深度
    n=1
    def test():
        global n
        print(n)
        n+=1
        test()
    
    test()
    
    虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归

    五、二分法

    想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

    l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
    
    def search(num,l):
        print(l)
        if len(l) > 0:
            mid=len(l)//2
            if num > l[mid]:
                #in the right
                l=l[mid+1:]
            elif num < l[mid]:
                #in the left
                l=l[:mid]
            else:
                print('find it')
                return
            search(num,l)
        else:
            #如果值不存在,则列表切为空
            print('not exists')
            return
    search(100,l)
    实现in的效果
    l=[1,2,10,30,33,99,101,200,301,402]
    
    def search(num,l,start=0,stop=len(l)-1):
        if start <= stop:
            mid=start+(stop-start)//2
            print('start:[%s] stop:[%s] mid:[%s] mid_val:[%s]' %(start,stop,mid,l[mid]))
            if num > l[mid]:
                start=mid+1
            elif num < l[mid]:
                stop=mid-1
            else:
                print('find it',mid)
                return
            search(num,l,start,stop)
        else: #如果stop > start则意味着列表实际上已经全部切完,即切为空
            print('not exists')
            return
    
    search(301,l)
    实现l.index(30)的效果

    六、匿名函数

    一、什么是匿名函数

    匿名就是没有名字
    def func(x,y,z=1):
        return x+y+z
    
    匿名
    lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字。:前是传入参数,:后是返回值
    func=lambda x,y,z=1:x+y+z 
    func(1,2,3)
    #让其有名字就没有意义

    二、有名字的函数与匿名函数对比

    #有名函数与匿名函数的对比
    有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
    
    匿名函数:一次性使用,随时随时定义
    
    应用:max,min,sorted,map,reduce,filter

    七、内置函数

    一、常用内置函数

    1、max/min函数

    max/min 后直接跟序列会返回此序列的最大/最小值:

    print(max(1,2,3))

    max(iterable, key, default) 求迭代器的最大值,其中iterable 为迭代器,max会for i in … 遍历一遍这个迭代器,然后将迭代器的每一个返回值当做参数传给key=func 中的func(一般用lambda表达式定义) ,然后将func的执行结果传给key,然后以key为标准进行大小的判断。

    以下根据不同的判断条件返回最大值也不同:

    d1 = {'name': 'egon', 'price': 100}
    d2 = {'name': 'rdw', 'price': 666}
    d3 = {'name': 'zat', 'price': 1}
    l1 = [d1, d2, d3]
    a = max(l1, key=lambda x: x['name'])
    print(a)
    b = max(l1, key=lambda x: x['price'])
    print(b)

    结果:

    {'name': 'zat', 'price': 1}
    {'name': 'rdw', 'price': 666}

    2、sorted函数

    sorted()函数可以接受一个参数

    sorted()函数还可以接受一个key函数来实现自定义的排序。

    sorted()还可以接受第三个参数:reverse=True,来实现反序排列

    #接受一个参数的例子如下: 
    sorted([5,-3,1])——————->结果[-3,1,5] 按大小进行排序
    
    #接受两个参数:除了要接收要排序的数据,还可以接收一个函数来满足此函数的要求进行排序,例如:
    sorted([5,-3,1],key=abs)————–>结果:[1,-3,5]
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    print(sorted(salaries,key=lambda k:salaries[k]))
    print(sorted(salaries,key=lambda k:salaries[k],reverse=True))
    
    ['yuanhao', 'egon', 'wupeiqi', 'alex']
    ['alex', 'wupeiqi', 'egon', 'yuanhao']

    3、map函数

    用于将一个或多个序列一一对应,转换成另一个序列

    格式: 
    map(func, seq1[, seq2,…]) 
    第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回一个迭代器对象。(3之前返回列表)

    1、当seq只有一个时,将函数func作用于这个seq的每个元素上,并得到一个新的seq。

    #使用lambda
    g=map(lambda x: x % 2, range(7))
    print(g)      #直接打印map函数得到的是内存地址,可以转化成列表查看
    print(list(g))
    
    <map object at 0x0000000002143F28> 
    [0, 1, 0, 1, 0, 1, 0]
    #把这个list所有数字转为字符串:
    print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
    ['1', '2', '3', '4', '5', '6', '7', '8', '9']

    2、当seq多于一个时,map可以并行(注意是并行)地对每个seq执行,每个seq的同一位置的元素同时传入一个多元的func函数之后,得到一个返回值,并将这个返回值存放在一个列表中。下面我们看一个有多个seq的例子:

    g=map(lambda x , y : x ** y, [2,4,6],[3,2,1])
    print(list(g))
    
    [8, 16, 6]

    需要注意的是: 
    map无法处理seq长度不一致、对应位置操作数类型不一致的情况,这两种情况都会报类型错误。

    4、filter函数

    用于过滤序列,也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

    filter函数的第一个参数func必须返回一个布尔值,即True或者False。

    filter(func,seq)

    names=['alex_sb','wupeiqi_sb','yuanhao_sb','egon']
    g=filter(lambda x:x.endswith('sb'),names)
    print(g)
    print(list(g))
    
    <filter object at 0x0000000001E2C2E8>
    ['alex_sb', 'wupeiqi_sb', 'yuanhao_sb']

    5、reduce函数

    reduce的用法,reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,如果有initial,则在序列最开始增加一个初始值,初始值作为序列的第一个元素。

    reduce(function, sequence, initial=None)

    from functools import reduce
    print(reduce(lambda x,y:x*10+y,range(1,3),100))
    
    10012

    6、divmod 函数

     函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。

    divmod(x, y)
    x:被除数
    y:除数
    print(divmod(5,2))
    
    (2, 1)

    7、enumerate函数

    为一个序列生成索引

    用法:

    enumerate(iterable[, start])

    iterable:可迭代对象

    start:指定初始值

    l=['a','b','c']
    for i,v in enumerate(l):
        print(i,v)
    
    0 a
    1 b
    2 c
    l=['a','b','c']
    for i,v in enumerate(l,2):
        print(i,v)
    
    2 a
    3 b
    4 c

    8、eval函数

    用来执行一个字符串表达式,并返回表达式的值。

    eval(expression[, globals[, locals]])
    参数:

    expression -- 表达式。

    globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。

    locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

    str='2+2'
    print(eval(str))
    
    4
    #也可以用于写在文件中的数据还原原本数据类型
    res=eval('[1,2,3]')
    print(res,type(res))
    
    [1, 2, 3] <class 'list'>

    9、exec函数

    exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码。

    语法:

    exec obj

    参数

    obj -- 要执行的表达式。

    返回值

    exec 返回值永远为 None。

    >>>exec 'print "Hello World"'
    Hello World
    # 单行语句字符串
    >>> exec "print 'runoob.com'"
    runoob.com
     
    #  多行语句字符串
    >>> exec """for i in range(5):
    ...   print "iter time: %d" % i
    ... """
    iter time: 0
    iter time: 1
    iter time: 2
    iter time: 3
    iter time: 4
    x = 10
    expr = """
    z = 30
    sum = x + y + z
    print(sum)
    """
    def func():
        y = 20
        exec(expr)
        exec(expr, {'x': 1, 'y': 2})
        exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
        
    func()
    
    
    60
    33
    34
    #返回值为空
    res=exec('[1,2,3]')
    print(res)
    
    None

    10、pow函数

    内置pow函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z

    注意:pow() 通过内置的方法直接调用,内置方法会把参数作为整型,而 math 模块则会把参数转换为 float。

    #以下是 math 模块 pow() 方法的语法:
    import math
    
    math.pow( x, y )

    内置的 pow() 方法

    pow(x, y[, z])

    =(x ** y)%z

    import math  # 导入 math 模块
    
    print("math.pow(100, 2) : ", math.pow(100, 2))
    # 使用内置,查看输出结果区别
    print("pow(100, 2) : ", pow(100, 2))
    print("pow(100, -2) : ", pow(100, -2))
    print("math.pow(100, -2) : ", math.pow(100, -2))
    print("math.pow(2, 4) : ", math.pow(2, 4))
    print("math.pow(3, 0) : ", math.pow(3, 0))

    结果:

    math.pow(100, 2) : 10000.0
    pow(100, 2) : 10000
    pow(100, -2) : 0.0001
    math.pow(100, -2) : 0.0001
    math.pow(2, 4) : 16.0
    math.pow(3, 0) : 1.0

     11、round函数

    返回浮点数x的四舍五入值。

    round( x [, n] )

    参数:

    x -- 数值表达式。

    n -- 保留后几位。

    #!/usr/bin/python
    
    print "round(80.23456, 2) : ", round(80.23456, 2)
    print "round(100.000056, 3) : ", round(100.000056, 3)
    print "round(-100.000056, 3) : ", round(-100.000056, 3)
    
    round(80.23456, 2) :  80.23
    round(100.000056, 3) :  100.0
    round(-100.000056, 3) :  -100.0

    12、zip()函数

    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

    如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

    zip 语法:
    zip([iterable, ...])
    
    参数说明:
    iterabl -- 一个或多个迭代器;
    
    返回值
    返回元组列表。
    >>>a = [1,2,3]
    >>> b = [4,5,6]
    >>> c = [4,5,6,7,8]
    >>> zipped = zip(a,b)     # 打包为元组的列表
    [(1, 4), (2, 5), (3, 6)]
    >>> zip(a,c)              # 元素个数与最短的列表一致
    [(1, 4), (2, 5), (3, 6)]
    >>> zip(*zipped)          # 与 zip 相反,可理解为解压,返回二维矩阵式
    [(1, 2, 3), (4, 5, 6)]

    二、了解的内置函数

    1、abs(x) 函数返回数字的绝对值。

    print(abs(-45))
    
    45

     2、all()

    函数用于判断给定的可迭代参数 iterable 中的所有元素是否不为 0、''、False 或者 iterable 为空,如果是返回 True,否则返回 False。

    注意:空元组、空列表返回值为True,这里要特别注意。

    all(iterable)

    iterable -- 元组或列表。

    >>>all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
    True
    >>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
    False
    >>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素
    False
       
    >>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
    True
    >>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
    False
    >>> all((0, 1,2, 3))          # 元组tuple,存在一个为0的元素
    False
       
    >>> all([])             # 空列表
    True
    >>> all(())             # 空元组
    True

    3、any()

    函数用于判断给定的可迭代参数 iterable 是否全部为空对象,如果都为空、0、false,则返回 False,如果不都为空、0、false,则返回 True。

    any(iterable)

    iterable--->可迭代元祖或列表

    >>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
    True
     
    >>> any(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
    True
     
    >>> any([0, '', False])        # 列表list,元素全为0,'',false
    False
     
    >>> any(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
    True
     
    >>> any(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
    True
     
    >>> any((0, '', False))        # 元组tuple,元素全为0,'',false
    False
      
    >>> any([]) # 空列表
    False
     
    >>> any(()) # 空元组
    False

    4、bin函数

    返回一个整数 int 或者长整数 long int 的二进制表示。、

    bin(x)

    x -- int 或者 long int 数字

    >>>bin(10)
    '0b1010'
    >>> bin(20)
    '0b10100'

    5、hex() 函数用于将10进制整数转换成16进制整数。

    >>>hex(255)
    '0xff'
    >>> hex(-42)
    '-0x2a'
    >>> hex(1L)
    '0x1L'

    6、oct() 函数将一个整数转换成8进制字符串。

    >>>oct(10)
    '012'
    >>> oct(20)
    '024'
    >>> oct(15)
    '017'
    >>>

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

    对于函数, 方法, lambda 函式, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True。

    >>>callable(0)
    False
    >>> callable("runoob")
    False
     
    >>> def add(a, b):
    ...     return a + b
    ... 
    >>> callable(add)             # 函数返回 True
    True
    >>> class A:                  #
    ...     def method(self):
    ...             return 0
    ... 
    >>> callable(A)               # 类返回 True
    True
    >>> a = A()
    >>> callable(a)               # 没有实现 __call__, 返回 False
    False
    >>> class B:
    ...     def __call__(self):
    ...             return 0
    ... 
    >>> callable(B)
    True
    >>> b = B()
    >>> callable(b)               # 实现 __call__, 返回 True
    True

    8、chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个以ascii表对应的字符。 

    可以是10进制也可以是16进制的形式的数字。

    >>>print chr(0x30), chr(0x31), chr(0x61)   # 十六进制
    0 1 a
    >>> print chr(48), chr(49), chr(97)         # 十进制
    0 1 a

     9、ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。

     返回值是对应的十进制整数。

    >>>ord('a')
    97
    >>> ord('b')
    98
    >>> ord('c')
    99

     10、dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。

    dir 语法:
    dir([object])
    参数说明: object
    -- 对象、变量、类型。
    返回值: 返回模块的属性列表。
    >>>dir()   #  获得当前模块的属性列表
    ['__builtins__', '__doc__', '__name__', '__package__', 'arr', 'myslice']
    >>> dir([ ])    # 查看列表的方法
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    >>>

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

    dir 语法:
    dir([object])


    参数说明:
    object -- 对象、变量、类型。

    返回值:

    返回新的 frozenset 对象,如果不提供任何参数,默认会生成空集合。。

    >>>a = frozenset(range(10))     # 生成一个新的不可变集合
    >>> a
    frozenset([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    >>> b = frozenset('runoob') 
    >>> b
    frozenset(['b', 'r', 'u', 'o', 'n'])   # 创建不可变集合

    12、hash() 用于获取取一个对象(字符串或者数值等)的哈希值。

    >>>hash('test')            # 字符串
    2314058222102390712
    >>> hash(1)                 # 数字
    1
    >>> hash(str([1,2,3]))      # 集合
    1335416675971793195
    >>> hash(str(sorted({'1':1}))) # 字典
    7666464346782421378
    >>>

     13、reversed()用于将一个列表元素翻转

    l=[1,2,'a',4]
    print(list(reversed(l)))

    [4, 'a', 2, 1]

    与reverse() 不同,reverse() 是直接对源列表进行修改,reversed()是新生成一个翻转的迭代器。

    l=[1,2,'a',4]
    l.reverse()
    print(l)
    
    [4, 'a', 2, 1]

     14、slice() 函数实现切片对象,主要用在切片操作函数里的参数传递。

    slice(stop)
    slice(start, stop[, step])

    参数说明:
    start -- 起始位置
    stop -- 结束位置
    step -- 间距
    返回值
    返回一个切片对象。

    >>>myslice = slice(5)    # 设置截取5个元素的切片
    >>> myslice
    slice(None, 5, None)
    >>> arr = range(10)
    >>> arr
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> arr[myslice]         # 截取 5 个元素
    [0, 1, 2, 3, 4]

    15、vars()函数

    vars() 函数返回对象object的属性和属性值的字典对象。

    vars() 函数语法:
    vars([object])
    
    参数
    object -- 对象
    
    返回值
    返回对象object的属性和属性值的字典对象,如果没有参数,就打印当前调用位置的属性和属性值 类似 locals()。
    >>>print(vars())
    {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
    >>> class Runoob:
    ...     a = 1
    ... 
    >>> print(vars(Runoob))
    {'a': 1, '__module__': '__main__', '__doc__': None}
    >>> runoob = Runoob()
    >>> print(vars(runoob))
    {}

     16、import作用:
    导入/引入一个python标准模块,其中包括.py文件、带有__init__.py文件的目录;

    __import__作用:
    同import语句同样的功能,但__import__是一个函数,并且只接收字符串作为参数,所以它的作用就可想而知了。其实import语句就是调用这个函数进行导入工作的,import sys <==>sys = __import__('sys')

    #实现用户输入选择导入模块
    choice=input('>>: ')
    print(choice,type(choice))
    
    # import 'time'
    m=__import__(choice)
    m.sleep(10)
    #字符串可以提供的参数 's' None
    >>> format('some string','s')
    'some string'
    >>> format('some string')
    'some string'
    
    #整形数值可以提供的参数有 'b' 'c' 'd' 'o' 'x' 'X' 'n' None
    >>> format(3,'b') #转换成二进制
    '11'
    >>> format(97,'c') #转换unicode成字符
    'a'
    >>> format(11,'d') #转换成10进制
    '11'
    >>> format(11,'o') #转换成8进制
    '13'
    >>> format(11,'x') #转换成16进制 小写字母表示
    'b'
    >>> format(11,'X') #转换成16进制 大写字母表示
    'B'
    >>> format(11,'n') #和d一样
    '11'
    >>> format(11) #默认和d一样
    '11'
    
    #浮点数可以提供的参数有 'e' 'E' 'f' 'F' 'g' 'G' 'n' '%' None
    >>> format(314159267,'e') #科学计数法,默认保留6位小数
    '3.141593e+08'
    >>> format(314159267,'0.2e') #科学计数法,指定保留2位小数
    '3.14e+08'
    >>> format(314159267,'0.2E') #科学计数法,指定保留2位小数,采用大写E表示
    '3.14E+08'
    >>> format(314159267,'f') #小数点计数法,默认保留6位小数
    '314159267.000000'
    >>> format(3.14159267000,'f') #小数点计数法,默认保留6位小数
    '3.141593'
    >>> format(3.14159267000,'0.8f') #小数点计数法,指定保留8位小数
    '3.14159267'
    >>> format(3.14159267000,'0.10f') #小数点计数法,指定保留10位小数
    '3.1415926700'
    >>> format(3.14e+1000000,'F')  #小数点计数法,无穷大转换成大小字母
    'INF'
    
    #g的格式化比较特殊,假设p为格式中指定的保留小数位数,先尝试采用科学计数法格式化,得到幂指数exp,如果-4<=exp<p,则采用小数计数法,并保留p-1-exp位小数,否则按小数计数法计数,并按p-1保留小数位数
    >>> format(0.00003141566,'.1g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点
    '3e-05'
    >>> format(0.00003141566,'.2g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留1位小数点
    '3.1e-05'
    >>> format(0.00003141566,'.3g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留2位小数点
    '3.14e-05'
    >>> format(0.00003141566,'.3G') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点,E使用大写
    '3.14E-05'
    >>> format(3.1415926777,'.1g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留0位小数点
    '3'
    >>> format(3.1415926777,'.2g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留1位小数点
    '3.1'
    >>> format(3.1415926777,'.3g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留2位小数点
    '3.14'
    >>> format(0.00003141566,'.1n') #和g相同
    '3e-05'
    >>> format(0.00003141566,'.3n') #和g相同
    '3.14e-05'
    >>> format(0.00003141566) #和g相同
    '3.141566e-05'
    format了解
    字典的运算:最小值,最大值,排序
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    
    迭代字典,取得是key,因而比较的是key的最大和最小值
    >>> max(salaries)
    'yuanhao'
    >>> min(salaries)
    'alex'
    
    可以取values,来比较
    >>> max(salaries.values())
    >>> min(salaries.values())
    但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
    >>> max(salaries,key=lambda k:salary[k])
    'alex'
    >>> min(salaries,key=lambda k:salary[k])
    'yuanhao'
    
    
    
    也可以通过zip的方式实现
    salaries_and_names=zip(salaries.values(),salaries.keys())
    
    先比较值,值相同则比较键
    >>> max(salaries_and_names)
    (100000000, 'alex')
    
    
    salaries_and_names是迭代器,因而只能访问一次
    >>> min(salaries_and_names)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: min() arg is an empty sequence
    
    
    
    sorted(iterable,key=None,reverse=False)
    
    !!!lambda与内置函数结合使用!!!
    !!!lambda与内置函数结合使用!!!
    #1、语法
    # eval(str,[,globasl[,locals]])
    # exec(str,[,globasl[,locals]])
    
    #2、区别
    #示例一:
    s='1+2+3'
    print(eval(s)) #eval用来执行表达式,并返回表达式执行的结果
    print(exec(s)) #exec用来执行语句,不会返回任何值
    '''
    6
    None
    '''
    
    #示例二:
    print(eval('1+2+x',{'x':3},{'x':30})) #返回33
    print(exec('1+2+x',{'x':3},{'x':30})) #返回None
    
    # print(eval('for i in range(10):print(i)')) #语法错误,eval不能执行表达式
    print(exec('for i in range(10):print(i)'))
    eval与exec
    compile(str,filename,kind)
    filename:用于追踪str来自于哪个文件,如果不想追踪就可以不定义
    kind可以是:single代表一条语句,exec代表一组语句,eval代表一个表达式
    s='for i in range(10):print(i)'
    code=compile(s,'','exec')
    exec(code)
    
    
    s='1+2+3'
    code=compile(s,'','eval')
    eval(code)
    complie(了解即可)

    练习:

    1、文件内容如下,标题为:姓名,性别,年纪,薪资

    egon male 18 3000
    alex male 38 30000
    wupeiqi female 28 20000
    yuanhao female 28 10000

    要求:
    从文件中取出每一条记录放入列表中,
    列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式

    2 根据1得到的列表,取出薪资最高的人的信息
    3 根据1得到的列表,取出最年轻的人的信息
    4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
    5 根据1得到的列表,过滤掉名字以a开头的人的信息
    6 使用递归打印斐波那契数列(前两个数的和得到第三个数,如:0 1 1 2 3 4 7...)

    7 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值

    #1
    with open('db.txt') as f:
        items=(line.split() for line in f)
        info=[{'name':name,'sex':sex,'age':age,'salary':salary} 
              for name,sex,age,salary in items]
    
    print(info)
    #2
    print(max(info,key=lambda dic:dic['salary']))
    
    #3
    print(min(info,key=lambda dic:dic['age']))
    
    # 4
    info_new=map(lambda item:{'name':item['name'].capitalize(),
                              'sex':item['sex'],
                              'age':item['age'],
                              'salary':item['salary']},info)
    
    print(list(info_new))
    
    #5
    g=filter(lambda item:item['name'].startswith('a'),info)
    print(list(g))
    
    #6
    #非递归
    def fib(n):
        a,b=0,1
        while a < n:
            print(a,end=' ')
            a,b=b,a+b
        print()
    
    fib(10)
    #递归
    def fib(a,b,stop):
        if  a > stop:
            return
        print(a,end=' ')
        fib(b,a+b,stop)
    
    fib(0,1,10)
    
    
    #7
    l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]
    
    def get(seq):
        for item in seq:
            if type(item) is list:
                get(item)
            else:
                print(item)
    get(l)
    View Code








  • 相关阅读:
    在mvc中,使用a链接,怎么转到别的html中
    mvc中怎么读取值传到后台中方法之一(表单传值法)
    mvc中怎么带参传递
    sqlserver去掉字符串结尾的全角空格并用半角替换
    Ajax学习笔记
    Ajax级联实例
    [转]js导航栏处于选中状态
    asp.net GridView的使用
    keycode大全
    IsPostBack的使用
  • 原文地址:https://www.cnblogs.com/guoyunlong666/p/8169309.html
Copyright © 2011-2022 走看看