python函数和集合
python函数
- 数学意义上的函数
- y = 2 x + 1 y=2x+1 y=2x+1,$y|_{x=3}=2×3+1=7
- 编程意义上的函数
Python中函数的定义:函数是逻辑结构化和过程化的一种编程方法。
函数是可以重复使用的程序段,在开放程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,
所以把具有独立功能的代码块组织为一个小模块,这就是函数。
它们允许你给一块语句一个名称,然后你可以在你的程序的任何地方使用这个名称任意多次地运行这个语句块,
值被称为调用函数,我们已经使用了许多内建的函数,比如len()range()。
函数定义和调用
函数定义
- 空函数
如果想定义一个什么事也不做的空函数,可以用pass语句。
def func():
pass
psss语句什么都不做,那有什么用?实际上pass可以用来作为站位符,比如现在还没想好怎么写函数的代码
,就可以先放一个pass,让代码能运行起来。
- 非空函数
函数通过def关键字定义。def关键字后跟一个函数的标识符名称,然后跟一对圆括号,圆括号之中可以包括一
些变量名,该行以冒号结尾,接下来是一块语句,它们是函数体。
声明函数的一般形式如下:
def 函数名(参数列表):
'''说明'''
函数语句
return 返回值
说明如下:
1.函数代码块以def关键字开头,后接函数标识符名称和小括号()。
2.任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
3.函数的第一行语句可以选择性地文档字符串……用于存放函数说明。
4.函数内容以冒号起始,并且缩进。
5.return[表达式]结束函数,选择性的返回一个值给调用方,不带表达式的return相当于返回None,其中参数列表
和返回值不是必须的return后也可以不跟返回值,甚至连return也没有。
对于return后没有返回值的和没有return语句的函数都会返回None值
有些函数可能概不需要转递参数,也没有返回值。
没有参数时,包含参数的圆括号也必须写上,圆括号后也必须由“:”。
现举一个简单例子:
def info():
"""打印信息"""
print({"name":"Tom","age":18})
info()
###函数调用
函数定义后,我们就具备了实现某种功能的代码,执行这些代码,只需要调用函数。
函数调用形式:函数名()
比如上面我们已经定义好了info()函数,现在我们调用:info()
现在整体写出代码:
# 定义函数
>>> def info():
... """打印信息"""
... print({"name":"tom","age":18})
# 函数调用
>>> info()
# 运行结果:
{'name': 'tom', 'age': 18}
练习:定义函数实现调用函数能够输出姓名,年龄
函数文档说明
在上面代码的基础上,添加:help(info)
运行后结果为:
Help on function info in module_main_:
info()
#打印信息
可以看到,help()返回info()函数的相关说明。
直接查看文档说明
# 输出注释
print(info._doc_)
# 打印信息
函数参数
假如我们需要定义一个函数计算两个数的积,有人设计如下函数:
def mul():
x = 3
y = 3
print(x*y)
mul() #9
这样可以吗?
这个函数只能实现3*3的结果,并不具备通用性。
为了让这个函数更具通用性,我们可以添加参数:
def mul(x,y):
print(x*y)
mul(3*6) # 调用
参数调用的顺序
我们先看一下以下例子:
>>> def test(x,y):
... print(x)
... print(y)
...
>>> test(1,2)
1
2
>>> test(x=1,y=2)
1
2
>>> test(y=2,x=1)
1
2
>>> test(1,y=2)
1
2
>>> test(x=1,2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>>
函数返回值
这里形象的解释一下函数:函数就是把一堆代码,打包放在那里,比如是一个发邮件的功能,然后这个功能被调用,说到这里大家应该会想知道,但是调的一个结果是啥?有没有成功?如果成功,干A事情,如果不超过做B的事情。
返回值的定义:函数外部的代码要想获得函数的执行结果,就可以在函数里用return语句把结果返回。
函数参数种类
首先,了解两个概念:形参和实参
-
1)形参:
- 只有在被调用是才分配内存单元,在调用结束时,即可释放所分配的内存单元,因此,形参只在函数内部有效,函数调用结束返回主调用函数后则不能再用改形参变量;
-
2)实参:
- 是从哪可以是常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,他们都必须有确定的值,以便把这些值传给形参,因此应预先用赋值,输入等办法使参数获得确定值;
def test(x,y):#test(x,y) 形参 print(x) print(y) test(1,2)# 1,2 实参 1 2
-
形参就是一把椅子,放在这里,占个位子而已,直到有人调用,赋值的时候才会分配内存单元,在调用结束,即可释放;
-
实参就是实实在在存在的,什么类型都接受
1.位置参数
>>> def mul(name,age,Hobbie,job="IT"):
... print("用户管理系统".center(16,'-')))
... print("\tName:\t",name)
... print("\tAge:\t",age)
... print("\tjob:\t",job)
... print("\tHobbie:\t",Hobbie)
... print("用户管理系统".center(16,'-')))
>>> mul("liuhao",17,job="IT",Hobbie="REad")
>>> mul("liuhao",17,"ghf","IT")
位置参数要以正确的顺序传入函数,调用时的数量必须和声明时的一样。
2.默认值参数
假如我们设置hobby值,即hobby=“Coding”。
>>> def mul(name,age,Hobbie,job="IT"):
... print("用户管理系统".center(16,'-')))
... print("\tName:\t",name)
... print("\tAge:\t",age)
... print("\tjob:\t",job)
... print("\tHobbie:\t",Hobbie)
... print("用户管理系统".center(16,'-')))
>>> mul("liuhao",17,"REad") #不传入参数,即为默认值
>>> mul("liuhao",17,"REad","Java") #传入参数,则改变值
>>> mul("liuhao",17,"REad","Html") #传入参数,则改变值
通过观察,可知:
如果定义默认值参数,在调用的时候,不给实参,就会调用默认参数。
如果函数定义修改为:
def mul(name,age,hobby="Coding",job):
运行将报错:
def mul(name,age,hobby="Coding",job):
SyntaxError: non-default argument default argument
因此,默认参数必须要放到位置参数的后边:
3.关键字参数
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键字,值需指定参数名即可(指定了参数名的参数就叫关键字)。
>>> def mul(name,age,job='IT',Hobbie='REad'):
... print("用户管理系统".center(16,'-'))
... print("\tName:\t",name)
... print("\tAge:\t",age)
... print("\tjob:\t",job)
... print("\tHobbie:\t",Hobbie)
... print("用户管理系统".center(16,'-'))
mul('Tom',age=22,HObbie="Coding",job="IT") #传参时,关键字参数可以位置改变
mul('LiLei',23,'IT','String') #不传关键字时,必须————对应
思考下列两种使用方法是否可以?
mul('Lucy',age=21,"IT","READ")
mul('Licy',22,"IT",age=21)
>>> mul('Lucy',age=21,"IT","Read")
#报错如下:
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> mul('Lucy',22,"IT",age=21)
#报错如下:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: mul() got multiple values for argument 'age'
>>>
关键字参数必须放在位置参数(以位置实现确定对应关系的参数)之后。
####4.不定参数
Python的不定参数,主要是指"args 和kwargs这两个魔法变量。那么它们到底是什么?
其实并不是必须写成*args和kwargs。只有变量前面的* (星号)才是必须的。也可以写成var和**vars。而写成args和kwargs只是一一个通俗的命名约定。
*args和kwargs 主要用于函数定义。我们可以将不定数量的参数传递给一一个函数。
这里的不定的意思是:预先并不知道,函数使用者会传递多少个参数给你,所以在这个场景下使用这两个关键字。
*args的用法
*args是用来发送一个非键值对的任意数量的可变数量的参数列表给一 个函数。 下面我们举例来帮助大家理解:
def uncertain_para(para,*args):
print("普通参数:",para)
print("不定参数:",args)
print(type(args))
for i in args:
print('逐一输出不定参数:',i)
uncertain_para(1,2,3,4,5)
# 运行后输出:
普通参数: 1
不定参数: (2, 3, 4, 5)
<class 'tuple'>
逐一输出不定参数: 2
逐一输出不定参数: 3
逐一输出不定参数: 4
逐一输出不定参数: 5
我们可以看出,在这个例子中, para接收了传递的第一一个参 数,而args则是由所有其他位置参数组成的元组。
**kwargs的用法
*kwargs允许我们将不定长度的键值对,作为参数传递给一个函数。
当我们想要在一一个函数里处理带名字的参数时,就可以使用**kwargs。
比如:
def uncertain para key(**kwargs):
print(type(kwargs))print(kwargs)
uncertain para key(a- 3,b=4,c=5)
运行后结果:
<class 'dict'>
{'a': 3, 'b': 4, 'c': 5}
*args和**kwargs的使用
def test_args_kwargs(para1,para2,para3):
print("para1:",para1)
print("para2:",para2)
print("para3:",para3)
args = ("abc",6,9)
print(test_args_kwargs(*args))
kwargs = {"para1":3,"para2":"xyz","para3":[1,2,3]}
print(test_args_kwargs(**kwargs))
运行后结果:
para1: abc
para2: 6
para3: 9
None
para1: 3
para2: xyz
para3: [1, 2, 3]
None
注意这里传递键值参数时,需满足参数数量-致,否则会报错。
标准参数与*args、**kwargs 在使用时的顺序
那么如果你想在函数里同时使用所有这三种参数,顺序是这样的:
func(fargs, *args, **kwargs)
举例如下:
def test_args_kwargs(para1,*para2,**para3):
print("para1:" , para1)
print("para2:" , para2)
print("para3:" , para3)
print(test_args_kwargs(1,2,3,4,5,a=6,b=7))
输出结果为:
para1:1
para2:(2,3,4,5)
para3:{'a':6,'b':7}
能加减乘除的函数:
def info(para1,para2,para3):
if para2 is "+" :
print(para1+para3)
elif para2 is "-" :
print(para1-para3)
elif para2 is "*" :
print(para1*para3)
elif para2 is "/" :
print(para1/para3)
elif para2 is "%" :
print(para1%para3)
集合
集合是无序的,不重复的且不可更改的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。以下是集合最重要的两点:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
集合的创建
创建一个空的集合
这里需要注意,我们不可以直接用花括号“{}”
>>> st=set()
>>> st
set()
>>> st1={}
>>> type(st),type(st1)
(<class 'set'>, <class 'dict'>)
多元素的集合创建
>>> st={"a","b","c","d","e"}
>>> st,type(st)
({'c', 'e', 'd', 'b', 'a'}, <class 'set'>)
>>> str = {1,2,3,4,[1,2]} #集合里面不能放可变的列表
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> str = {1,2,3,4,{"a":2}} #集合里面不能放可变的字典
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> str = {1,2,3,4,(1,2)}
>>> str
{(1, 2), 1, 2, 3, 4}
>>>
集合的强转
>>> li = [1,"a","n","hunan"]
>>> st_li=set(li)
>>> st_li,type(st_li)
({1, 'n', 'a', 'hunan'}, <class 'set'>)
>>>
>>> str = "version"
>>> st_str = set(str)
>>> st_str,type(st_str)
({'v', 'i', 's', 'e', 'n', 'o', 'r'}, <class 'set'>)
>>> dic = {"a":1,"b":2,"c":3,"d":4}
>>> st_dic = set(dic)
>>> st_dic , type(st_dic)
({'c', 'b', 'a', 'd'}, <class 'set'>)
>>> tp = (1,2,3,4)
>>> st_tp=set(tp)
>>> st_tp,type(st_tp)
({1, 2, 3, 4}, <class 'set'>)
- list()
- str()
- tuple()
- dict()
- set()
集合的基本操作
查
- 无序,不可查找
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st[2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing
增
- set.add() #随机添加进集合
- set.update() #会拆掉字符一个一个加到集合里面
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st.add("Comper Server")
>>> st
{1, 2, 'Hunan', 'yingxiao', 'Comper Server', 'Coll'}
>>> st.update("湖南","长沙")
>>> st
{1, 2, 'Hunan', 'yingxiao', 'Comper Server', '长', '南', '湖', '沙', 'Coll'}
删
- set.pop() #删除排序最小的一个
- set.discard() #移除指定元素,没有指定元素不会报错
- set.remove() #移除指定元素,没有指定元素会报错
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st.pop() #删除排序最小的一个
1
>>> st
{2, 'Hunan', 'yingxiao', 'Coll'}
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st.discard(2) #移除指定元素
>>> st
{1, 'Hunan', 'yingxiao', 'Coll'}
>>> st.discard(3) #如果元素不存在,不会报错,不做任何操作
>>> st
{1, 2, 'Hunan', 'yingxiao', 'Coll'}
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st.remove(2)
>>> st
{1, 'Hunan', 'yingxiao', 'Coll'}
>>> st.remove('Coll')
>>> st
{1, 'Hunan', 'yingxiao'}
>>> st.remove(3) #没有指定元素会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 3
- set.clear() #删除集合所有元素
- del set名 #删除整个集合
>>> st = {1,2,3}
>>> st.clear()
>>> st
set()
>>> st = {1,2,3}
>>> del st
>>> st
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'st' is not defined
>>>
改
不可以更改
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> st[0] = "BeiJin"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support item assignment
>>>
遍历
一:
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> for i in st:
... print(i,end=" ")
...
1 2 Hunan yingxiao Coll >>>
二:
>>> st = {1 ,2 ,"Hunan","yingxiao","Coll"}
>>> for index,value in enumerate(st):
... print(index,value)
...
0 1
1 2
2 Hunan
3 yingxiao
4 Coll
比较
集合的基本运算
###子集
issubset():判断集合 a 的所有元素是否都包含在集合 c 中
>>> a = set("abcd")
>>> b = set("cdef")
>>> c = set("ab")
>>> a,b,c
({'c', 'b', 'a', 'd'}, {'f', 'c', 'e', 'd'}, {'b', 'a'})
>>> c.issubset(a) #子集
True
>>> c < a
True
>>> c < b
False
###交集
intersection():该集合的元素既包含在集合 a 又包含在集合 b中
>>> a = set("abcd")
>>> b = set("cdef")
>>>
>>> a.intersection(b)
{'c', 'd'}
>>> a & b
{'c', 'd'}
并集
union():合并两个集合,重复元素只会出现一次
>>> a = set("abcd")
>>> b = set("cdef")
>>> a.union(b)
{'c', 'f', 'e', 'd', 'b', 'a'}
>>> a | b
{'c', 'f', 'e', 'd', 'b', 'a'}
>>>
差集
difference():返回一个集合,元素包含在集合 a ,但不在集合 b
>>> a = set("abcd")
>>> b = set("cdef")
>>> a.difference(b)
{'b', 'a'}
>>> a - b
{'b', 'a'}
>>>