4.1 函数:

4.1.1、  概念

4.1.2、  创建

4.1.3、  参数

4.1.4、  函数的reture

    4.1.5、  定义域

    4.1.6、  filter

    4.1.7、  map

    4.1.8、  reduce

    4.1.9、  迭代器

    4.1.10、 装饰器

    4.1.11、 内置函数

4.2:深浅拷贝

    4.2.1、  浅拷

    4.2.2、  深拷贝

all 判断是否有空元素   返回值为True或False

eval() 转换为字典 也能直接求出结果  eval('1+3+2')

4.1 函数:

4.1.1、概念

作用:

1、减少重复代码

2、方便修改,易扩展

3、保持代码一致性

命名规则

函数名必须是下划线或字母开头, 可以包含任意字母、数字或下划线的组合, 不能使用任何标点符号

函数名是不区分大小写的;

函数名不能是保留字。

4.1.2、创建

def f(): # def是define简称  f()表示函数名  ()可以用来传递参数

print (" hello world ")   # 函数体,下面所有代码都属于 f 这个函数

f()# 调用函数, 不加(), 直接用f那么它就表示成了一个变量

4.1.3、参数 

# 注意:1、形参有多少个,实参就得定义多少个

2、调用时候需要严格区分大小写

3、默写参数一定要跟在其它参数后面

4、不定长参数, 固定格式: (*args无命名参数放左边,**kwargs 有命名参数放右边),如果有默认参数放左边

# 必须参数(关键字参数): 必须参数以正确顺序传入函数,调用时的数量必须和声明时的一样

    def add(x,y):# add(x,y) 形参    print (x+y)    def(3,5)# 实参    def test1(name,age):        print("Name: %s" % name )        print("Age: %d" % age )    test1("xiong",123)

打印结果: Name: xiong

   Age: 123

# 默认参数:

    def test1(name,age,sex="man"):        print("Name: %s" % name )        print("Age: %d" % age )        print("Sex: %s " % sex )test1("xiong",123)打印结果: Name: xiong   Age: 123   Sex: man

# 不定长参数:(*args)    # args可以自行命名   *表示不定长参数   

(*arges):   无命名参数   # 保存至args时为元组

(**kwargs): 有命名参数 # 保存至kwargs时为字典

*args 使用方法

    a=(1,2,3,4,5)

    a=(*[1,2,3,4,5])

**kwargs  把N个关键字参数,转换成字典的方式

    a=(name="xiong",sex='m')    a=(**{'name':'xiong','sex':'m'})    def test2(*args):        print(args)

 

test2(1,2,3,4,5,6)          # 打印结果为: (1, 2, 3, 4, 5, 6)

##################### 示例2 #####################

def test3(**kwargs):

    print(kwargs)

 

test3(name="xiong",age=123,sex="man")    # 打印结果: {'name': 'xiong', 'age': 123, 'sex': 'man'}

##################### 示例3 #####################

def test3(**kwargs):    for te in kwargs:        print(te,":",kwargs[te])

         

test3(name="xiong",age=123,sex="man")  

# 打印结果: name : xiong

             age : 123

             sex : man

##################### 示例4 #####################

def test4(*args,**kwargs):

    print(args,kwargs)

 

test4(1,2,3,4,name="xiong",age=123,sex="man")  

# 打印结果: (1, 2, 3, 4) {'name': 'xiong', 'age': 123, 'sex': 'man'}

##################### 错误——示例5 #####################

def test4(name,sex="man",*args,**kwargs):    print(name,sex,args,kwargs) test4(name="xiong",sex="man",1,2,3,4,age=123)# 打印结果: SyntaxError: positional argument follows keyword argument

# 优先级: def 函数名(关键参数,默认参数,无命名参数,有命名参数)

#示例  def test(te1,age='male',123,job='IT')

#########  当中间有一个默认值的时候,如果不指定它还是会打印出错,

def test4(name,sex="man",*args,**kwargs):

    print(name,sex,args,kwargs)

 

test4("xiong",1,2,3,4,age=123)

4.1.4、函数的reture

作用: 1、结束函数

   2、返回某个对象

注意点: 1、 函数里如果没有return,会默认返回一个None

2、 如果return有多个对象,那么python会帮我们把多个对象封装成一个元组返回

4.1.5、定义域

函数是有自己的定义域的,IF是没有的

作用域分四种情况: LEGB

L:local,局部作用域,即函数中定义的变量;

E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

G:globa,全局变量,就是模块级别定义的变量;

B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB

外层 built-in --> global 全局作用域 --> enclosing 局部作用域 --> local 局部作用域

局部变量不能修改全局变量

局部要想改变全局变量需要增加一个global 变量

如果是在enclosing那就需要增加一个nonlocal 变量名称 

4.1.6:filter (函数名字, 序列)过滤器对象

filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list

# 过滤列表中名称是xiong的字符串

            name=["xiong","yuan"]            def fi(n):                if n!="xiong":                    return n            let=filter(fi,name)            print(list(let))                # 结果 ['yuan']

# 再比如过滤掉数字为奇数的行

            def number(n):                if n %2 ==1:                    return n            jnum=filter(number,range(1,20))     # 过滤对象内存地址:
            print(list(jnum))                   # 打印结果就是:[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

4.1.7 map (函数名字, 序列)

map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

map()函数是python内置的高阶函数,对传入的list的每一个元素进行映射,返回一个新的映射之后的list

            def x(f):                return f*f      #从9开始每次相乘            num=map(x,range(9))            print(list(num))                   0  1  2  3   4   5  6    7  8  每个值都乖以自己

# 结果: 等于就是每个值的平方 [0, 1, 4, 9, 16, 25, 36, 49, 64]

  注意:map()函数不改变原有的 list,而是返回一个新的 list。

由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。

            x=["ali","jic","you"]            def name(x):                return "a" + x                  na=map(name,x)              # 跟filter差不多,但如果将map改为filter那么它返回的结果就是ali,jic,you            print(list(na))                # 结果: ['aali', 'ajic', 'ayou']

# 扩展信息: http://www.cnblogs.com/superxuezhazha/p/5714970.html

4.1.8 reduce(函数,对象或序列)

reduce()   # 想用这个方法必须加上如下参数    reduce的结果就是一个值 

         from functools import reduce 

        lambda a,b: a + b

        ## 示例 先调用这个函数 

        from functools import reduce        # add = lambda a,b: a+b        # print(add(1,2))           # 结果3        def add1(x,y):            return x + y        print(reduce(add1,range(10)))   # 结果45

4.1.9、迭代器 (函数名字, 序列)过滤器对象

# 什么是迭代器?  迭代器包含生成器

            # 满足两个条件:1、有iter方法, 2、有next方法

    # 自己理解

       # for 循环 先将(元组,字典,列表,集合,元组) 使用__iter__() 转换成迭代器对象,然后再使用__next__()方法从上往下取出结果

   # 专业解释

      # 调用它们内部的__iter__()方法,把它们变成可迭代对象,然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉stopiteration异常,以终止迭代

        # for  循环内部三件事:

            1、 调用可迭代对象的iter方法返回一个迭代器对象

            2、 不断调用迭代器的next方法

            3、 处理 StopIteration

        # 生成器都是迭代器,迭代器不一定是生成器 能使用iter的可迭代对象

            l=[1,2,4,5]

            d=iter(l)

            print(d)        # 结果 <list_iterator object at 0x000000000063B1D0>

        Iterator 可迭代对象  Iterable 迭代器

        isinstance 判断对象是啥类型 

        from collections import Iterator    # 需要先调用这个类型才能使用isinstance方法

        print(isinstance([1,2,3],list))

 迭代器用法:

people_list=['xiong','yuan','xyz']print('土地拍卖现在开始啦')def pow(people_list):    if len(people_list) == 0:        return '没人获取了'    person=people_list.pop(0)    if person == "xyz":        return '恭喜%s成功拍下'%person    print('%s 加500W 还有没有要加的?'%person)    res=pow(people_list)    print('%s 结果: %res' %(person,res))    return resres=pow(people_list)print(res)

4.1.10、 装饰器

    装饰器:为其它函数增加功能使用的

    原则:  1、不能修改被装饰的函数的源代码

            2、不能修改被装修的函数的调用方式

    装饰器

        1、函数即“变量”, 变量特性内存回收机制,只要变量存在,内存地址将不会被删除 

        2、高阶函数

            2.1、 满足函数名可以做为一个参数输入 (在不修改被装饰函数源代码的情况下为其添加功能)

            2.2、 函数名还可以做为返回值

        3、嵌套函数

            高阶函数+嵌套函数 ==> 装饰器

    定义:如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包

    def xx():        x=10:               def yy():           # 条件一 xx就是内部函数            print(x)        # 条件二 外部环境的一个变量        return yy           # 结论: 内部函数inner就是一个闭包
    # 装饰器import timedef change(func):    def wapper():        start_time=time.time()      # 调用之后先来个时间        func()              # 需要注意的是 func就是直接调用tests函数        end_time=time.time()       # 调用之后的时间        print('函数执行总时长: %s'%(end_time-start_time))    return wapper       # 返回的是一个函数的内存指向地址@change                  # 语法糖def tests():    time.sleep(2)    print('_主体函数_')# @change 完全等于 tests=change(tests)tests()

 

   列表生成式:  生成器就是一个可迭代对象(Iterable)

        a=[x*x for x in range(10)]      直接计算出平方结果[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

        a=(x*x for x in range(10))      打印出生成器对象,不会有结果

                                        <generator object <genexpr> at 0x00000000021669E8>

        a.__next__()   # 使用该内置方法可以将值打印出来,但是不建议使用

        建议使用 print(next(a)) 方法          py2中使用的是s.next()

                只能从0开始到最后

#  功能,设置一个函数时间,将其保存到测试文件中,将打印start funcation 到屏幕上

    #!/usr/bin/env python    # -*- coding:utf-8 -*-     def logger(n):        import time        time_format = "%Y-%m-%d %X"        times = time.strftime(time_format)         with open("测试文件",'a',encoding='utf-8') as f:            f.write("%s funcation1 %s \n" %(times,n) )     def fun1(n):        print("start funcation 1 ")        logger(n)     fun1(1)

 

# 打印结果打开测试文件  2017-09-12 14:13:33 funcation1 1  

                    #   %s  times                      %s  n    函数形参的参数

# 实现不定长函数的加法

def test2(*args):    number = 0    for i in args:        number += i    print(number)

 

test2(1,2,3,4,5,6)      # 传递一堆整型给test2函数, 保存至args是元组格式,使用for循环叠加

4.1.11、 内置函数

b = 'abc1'b.count('1')#统计元素个数结果 1b.capitalize()#字符串首字母大写结果 Abc1b.center(12,'-')#字符居中并两边打印- 结果 ----abc1----print('abc'.ljust(50,'*'))向左对齐print('abc'.rjust(50,'*'))向右对齐print("   xiong   ".strip())去除所有空格,换行符也会自动取消  很重要的方法print( 'xiong'.replace('x','X',1))替换 #两个参数,(想更改的),(要更改成啥),如有多个字符,1表示只替换一次b.encode#编码b.endswith('1')#以某个字符串结尾结果 Trueb.startswith('1')#以某个字符串起始结果 Falseb.expandtabs(tabsize=#)# 用得少b.find('1')#查找第一个元素,并将索引值返回print('xiong'.rfind('g'))#与find功能一样print('xiong'.find('g'))两个打印结果都是: 4b.index('1')#与find功能一样,多了一个元素没有的时候会报错,find不会报错b.format#格式化输出的另一种方式b = 'abc1 {name} is {age}'print(b.format(name='xiong',age='123'))b.format_map({'name':'xiong','age':'123'})print(str.isalnum()) # 判断所有字符都是数字或者字母print(str.isalpha()) # 判断所有字符都是字母print(str.isdigit()) # 判断所有字符都是数字 必须是一个×××print(str.islower()) # 判断所有字符都是小写print(str.isupper()) # 判断所有字符都是大写print(str.istitle()) # 判断所有单词都是首字母大写,像标题print(str.isspace()) # 判断所有字符都是空白字符、\t、\n、\r# 返回结果不是True 就是 Falseprint('Abc',lower()) # 大写变小写结果abcprint('Abc',upper()) # 小写变大写结果ABCprint('Abc',swapcase()) # 小写变大写,大写变小写    结果 aBCprint ('My test xiong'.split(' '))将字符串变为一个列表  # split(' ',1)   以什么为分隔符进行分割字符串 ['My', 'test xiong']print ('My test xiong'.rsplit(' '))将字符串变为一个列表  # rsplit(' ',1) 从右往左, 只分隔一次   ['My test', 'xiong']print ('My test xiong'.title())    所有字符串 首字母都变成大写  My Test Xiongjoin 连接方法   拼接   方法为 ''.join(字符串提供的方法)a='123'b='abc'c=''.join([a,b])#结果 123abcc='****'.join([a,b])#结果 123****abcflush: 将数据从缓存区取出同步保存与磁盘中import sys,timesys.stdout.write("*")# 截断是在写模式下操作的,必须使用write,append格式truncate    # 清空文件内容fileno# 文件描述符isatty# 查看是不是终端设备zip 拉链方法    print(list(zip('a','b')))   #将两个字符串组成一个元组    结果: [('a', 'b')]    print(zip(('b','c'),(1,2)))  # 直接打印就是一个内存对象地址 结果
  # 需要将内存地址列出才能查看 ,左边一对应右边一    print(list(zip(('b','c'),(1,2))))  # 结果[('b', 1), ('c', 2)]# 当右边没有对应值时,就不会组成对应元组,    print(list(zip(('b','c','d'),(1,2))))   #结果[('b', 1), ('c', 2)]# 将字典也可以转成一一对应的元组    dic={'name':'xiong','age':121}    print(list(zip(dic.keys(),dic.values())))    # 结果:[('name', 'xiong'), ('age', 121)]    max | min的用法, max最大,min最小# max传递的参数必须是可迭代的,也就是可以用for进行循环的类型print(list(max(zip(name.values(),name.keys()))))# max比较的类型必须是同一种类型,比如现在是字符串,那么中间有整型比较一定会报错name=['a11','b11','c11']  # 字符串比较是从第一位开始,第一位如果大那么这个字符串无论多长都是最大的print(max(name))name2=['A11','c11','a1']print(max(name2))print(bin(1))print(hex(21))# max的高级用法 ,比较数据的最大大小    dit=[        {'name':'xiong','age':123},        {'name':'yy','age':312},        {'name':'ss','age':4221},        {'name':'za','age':1243},    ]    print(max(dit,key=lambda age:age['name']))    # {'name': 'za', 'age': 1243}    print(max(dit,key=lambda age:age['age']))    # {'name': 'ss', 'age': 4221}        # 相当于先return了一个age的最大数值,然后将数值进行比较    it=[]    for item in dit:        it.append(item['age'])    print(it)    # sorted从小到大排序dic={     'uu_age':50,     'xx_age': 51,}# sorted 字典默认排序会直接使用key的方式print(sorted(dic))# 结果['uu_age', 'xx_age']# 使用values进行比较,但打印出来的只是名称,不是数值print(sorted(dic,key=lambda age:dic[age]))# 结果['uu_age', 'xx_age']# 以列表的方式打印出结果print(sorted(zip(dic.values(),dic.keys())))# 结果[(50, 'uu_age'), (51, 'xx_age')]# reversed 倒序排列li=[1,2,3,4,5]          print(list(reversed(li)))

4.2 深浅拷贝

4.2.1 浅拷 = 相当于软链接

# 变量中列表就相当于文件,int与str就相当于是一个目录,

# (软链接可以将目录名称更称不会修改文件本身,但如果修改文件那么A跟B就会同时修改)。

a = [[1,2],3,4]print(a)打印: [[1, 2], 3, 4]b = a.copy()b[1]=321print(b)打印结果为: [[1, 2], 321, 4]# 软链接目录名称改了也不会影响原来的目录print(a)打印结果为: [[1, 2], 3, 4]# b修改a不修改也就正常了# 但如果是修改变量中的列表时,它会修改内存中指的值,a跟b会同时修改b[0][1] = 234print(b)print(id(b[0][1]))# 打印结果为: 1388964880   两个内存结果都一样print(a)打印结果为: [[1, 234], 321, 4]# 改了软链接中文件,那么2个文件都会同时更称[[1, 234], 3, 4]print(id(a[0][1])) # 打印结果为: 1388964880   # 相当于一个链接的文件,修改b也相当于修改a了

4.2.2 深拷贝 = 完整克隆

变量 = copy.deepcopy(要复制的变量)    # 完整克隆一个数据