|
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)) # 过滤对象内存地址:<filter object at 0x000000000250F828>
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 res
res=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 time
def 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')#统计元素个数结果 1
b.capitalize()#字符串首字母大写结果 Abc1
b.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')#以某个字符串结尾结果 True
b.startswith('1')#以某个字符串起始结果 False
b.expandtabs(tabsize=#)# 用得少
b.find('1')#查找第一个元素,并将索引值返回
print('xiong'.rfind('g'))#与find功能一样
print('xiong'.find('g'))
两个打印结果都是: 4
b.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 就是 False
print('Abc',lower()) # 大写变小写结果abc
print('Abc',upper()) # 小写变大写结果ABC
print('Abc',swapcase()) # 小写变大写,大写变小写 结果 aBC
print ('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 Xiong
join 连接方法 拼接 方法为 ''.join(字符串提供的方法)
a='123'
b='abc'
c=''.join([a,b])#结果 123abc
c='****'.join([a,b])#结果 123****abc
flush: 将数据从缓存区取出同步保存与磁盘中
import sys,time
sys.stdout.write("*")
# 截断是在写模式下操作的,必须使用write,append格式
truncate # 清空文件内容
fileno# 文件描述符
isatty# 查看是不是终端设备
zip 拉链方法
print(list(zip('a','b'))) #将两个字符串组成一个元组 结果: [('a', 'b')]
print(zip(('b','c'),(1,2))) # 直接打印就是一个内存对象地址 结果<zip object at 0x000000000250E508>
# 需要将内存地址列出才能查看 ,左边一对应右边一
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]=321
print(b)
打印结果为: [[1, 2], 321, 4]# 软链接目录名称改了也不会影响原来的目录
print(a)
打印结果为: [[1, 2], 3, 4]# b修改a不修改也就正常了
# 但如果是修改变量中的列表时,它会修改内存中指的值,a跟b会同时修改
b[0][1] = 234
print(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(要复制的变量) # 完整克隆一个数据 |
|