函数

函数

引子:

要求1-15的和;

求23-36的和;

求55-68的和。

def sum(a,b):
    sum = 0
    for i in range(a,b+1):
        sum += i
    return sum
print(sum(1,15))
print(sum(23,36))
print(sum(55,68))

120
413
861

对于程序而言:函数就是一个对程序逻辑进行结构化或者过程化的一种编程方法。

built-in function 内置函数 —> BIF

函数的定义

声明函数的一般形式:

def function_name(arg1,arg2,...,argn):
    '''statements'''
    func_statements
    return Value

说明如下:

​ 1.函数代码块以 def 关键词开头,后接函数标识符名称和小括号 ()。

​ 2.任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

​ 3.函数的第一行语句可以选择性地使用文档字符串----用于存放函数说明。

​ 4.函数内容以冒号起始,并且缩进。

​ 5.return [表达式] 结束函数,选择性的返回一个值给调用方。不带表达式的return相当于返回 None。

​ 其中参数列表和返回值不是必须的,return后也可以不跟返回值,甚至连 return也没有。

​ 对于return后没有返回值的和没有return语句的函数都会返回None值

​ 有些函数可能既不需要传递参数,也没有返回值。

​ 没有参数时,包含参数的圆括号也必须写上,圆括号后也必须有“:”。

函数调用

函数文档说明

函数参数

  • 不传参函数
  • 参数函数
    • 顺序

函数返回值

函数参数种类

形参和实参

  • 形参

    • 只有在调用时才分配内存单元,调用结束后,立即释放所分配的内存单元。因此,形参只在内部有效,函数调用结束返回主调用函数后则不能再使用该形参变量
  • 实参

    • 实参是一个确定的值,能够传递给形参
      • 作为位置参数或者关键字参数传递

位置参数

def usr_manage(name,age,job,hobby):
    print("用户管理系统".center(16,'-'))
    print("\tName:\t",name)
    print("\tAge:\t",age)
    print("\tjob:\t",job)
    print("\thobby:\t",hobby)
    print("用户管理系统".center(16,'-'))
usr_manage("Tom",20,"IT","Coding")
usr_manage("Jim",21,"Student","Reading")

只传递参数,位置 —对应—>位置参数

使用位置参数时和函数头定义的形参在顺序,个数以及类型上匹配。

默认值参数

def usr_manage(name,age,job,hobby = "Trip"):
    print("用户管理系统".center(16,'-'))
    print("\tName:\t",name)
    print("\tAge:\t",age)
    print("\tjob:\t",job)
    print("\thobby:\t",hobby)
    print("用户管理系统".center(16,'-'))
usr_manage("Tom",20,"IT","Coding")
usr_manage("Jim",21,"Student")

关键字参数

def usr_manage(name,age,job="IT",hobby = "Trip"):
    print("用户管理系统".center(16,'-'))
    print("\tName:\t",name)
    print("\tAge:\t",age)
    print("\tjob:\t",job)
    print("\thobby:\t",hobby)
    print("用户管理系统".center(16,'-'))
usr_manage("Tom",20,hobby="Coding",job="Student")
usr_manage("Jim",21,"Student")

默认值参数,关键字参数,必须放置于位置参数之后。

不定参数

在Python中不定参数主要指*args**kwargs两个魔法变量。

他们俩主要是用于函数定义,我们可以将不定数量的参数传递给一个函数。

  • *args用来接收任意非键值对的任意数量的参数列表给函数
def uncertain_para(para,*args):
    print("普通位置参数:",para)
    print("不定参数:",args)
    print(type(args))
uncertain_para(1,2,3,4,'a','b')
uncertain_para([1,2,3],"ab","cd","ef")

普通位置参数: 1
不定参数: (2, 3, 4, 'a', 'b')
<class 'tuple'>
普通位置参数: [1, 2, 3]
不定参数: ('ab', 'cd', 'ef')
<class 'tuple'>
  • **kwargs用来接收任意不定长度的键值对列表
def un_para_key(a,b,*c,**kwargs):
    print(a,b,c,kwargs)
    print(type(kwargs))
un_para_key(1,2,3,4,5,'a','b',e=1,r=2,g=3,d=4)

1 2 (3, 4, 5, 'a', 'b') {'e': 1, 'r': 2, 'g': 3, 'd': 4}
<class 'dict'>

练习:写一个函数,计算传入字符中的数字,字母,空格以及其他字符的个数

str = input("请输入字符串:")
def count(str):
    num,alpha,blank,other = 0,0,0,0
    for char in str:
        if char.isdigit():
            num += 1
        elif char.isalpha():
            alpha += 1
        elif char.isspace():
            blank += 1
        else:
            other += 1
    print("数字个数:{},字母个数:{},空格个数:{},其他字符个数:{}".format(num,alpha,blank,other))
count(str)

函数引用

函数属性

函数属性是Python中另外一个使用了句点属性标识并拥有名字空间的领域。

你可以获得每个 python 模块,类,和函数中任意的名字空间。你可以在模块 foo 和 bar 里都有名为 x 的一个变量,,但是在将这两个模块导入你的程序后,仍然可以使用这两个变量。所以,即使在两个模块中使用了相同的变量名字,这也是安全的,因为句点属性标识对于两个模块意味了不同的命名空间,比如说,在这段代码中没有名字冲突:

python -i 文件名.py(运行脚本,同时进入解释器)

def foo():
    'foo --- Properly created doc string'

def bar():
    pass

bar.__doc__ = "Oops,forget the doc str above"
bar.version = 0.1

print(bar.__doc__)

内嵌函数

---->作用域

bar()整个函数都处于外部foo()函数的作用域里(foo()是我们可以从外部访问的一个对象区域)。除了在foo()内部,其他地方无法对bar函数进行调用。

变量作用域

作用域的产生

就作用域而言,python和C有很大差别,只有当变量在module,Class,函数中定义的时候,才会有作用域的概念。

def foo():
    a = "foo"
    print(a)
foo()
print(a)

foo
Traceback (most recent call last):
  File "D:/python/PycharmProjects/chenhan/day06.py", line 144, in <module>
    print(a)
NameError: name 'a' is not defined

if True:
    a = 100
    print(a)
print("-"*5)
print(a)

100
-----
100

在作用域中定义的变量,一般只在作用域内有效。需要注意的是,在if-elif-else,for-else,while-else,try-except(else_finally)等关键字的语句块中不会产生作用域。

作用域的类型

Python中,使用一个变量时并不要求需要预先声明它。但在正真使用的时候,它必须绑定到某个内存对象(被定义,赋值)。这种变量名的绑定将在当前作用域引入新的变量,同时,屏蔽外层作用域中的同名变量。

  • 局部作用域(locale —L)

    • 局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
      注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。
  • 嵌套作用域(enclosing — E)

    • E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对于一个函数而言,L是定义在此函数内部的局部作用域。
    • 主要为了实现python的闭包,而增加的实现。
  • 全局作用域(Global — G)

    • 即在模块层次中定义的变量。模块顶层声明的变量具有全局作用域。从外部来看,模块的全局变量就是一个模块对象的属性。
  • 内置作用域(built-in — B)

    • 系统固定模块中定义的变量。

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

全局变量和局部变量

gbl_str = "foo"
def foo():
    loc_str = "bar"
    return gbl_str + loc_str
print(foo())
print(gbl_str)
print(loc_str)

foobar
Traceback (most recent call last):
foo
  File "D:/python/PycharmProjects/chenhan/day06.py", line 152, in <module>
    print(loc_str)
NameError: name 'loc_str' is not defined
a = 6688
def foo():
    #a = 666
    print("foo(),a:\t",a)
    a = 888
    print("foo(),a:\t", a)
def bar():
    print("bar(),a:\t",a)

foo()
bar()

Traceback (most recent call last):
  File "D:/python/PycharmProjects/chenhan/day06.py", line 186, in <module>
    foo()
  File "D:/python/PycharmProjects/chenhan/day06.py", line 180, in foo
    print("foo(),a:\t",a)
UnboundLocalError: local variable 'a' referenced before assignment
#优先搜索局部变量a,但在a被定义之前a已经被引用,报错

global

a = 6688
def foo():
    a = 666
    def inner_foo():
        global  a
        print("change before",a)
        a = 888
        print("change after", a)
    inner_foo()
    print(a)

print(a)
foo()
print(a)

6688
change before 6688
change after 888
666
888

可变类型的全局变量

a = 666
def foo():

    a += 1
    print(a)
foo()

Traceback (most recent call last):
  File "D:/python/PycharmProjects/chenhan/day07.py", line 28, in <module>
    foo()
  File "D:/python/PycharmProjects/chenhan/day07.py", line 26, in foo
    a += 1
UnboundLocalError: local variable 'a' referenced before assignment

递归函数

在一个函数体的内部,调用函数本身,就被称为递归函数

匿名函数(lambda)

格式:

lambda para1,para2,...,paran:exp(para1,para2,...,paran)

demo:

f = lambda x,y,z:x+y+z
print(f(1,2,3))

6

f = lambda x="city",y="college",z="zucc":x+y+z
print(f())

citycollegezucc

高阶函数

  • 把一个函数名,以实参的形式,传递给这个函数的形参
def add(a,b,c):
    return c(a)+c(b)
a_value = add(-9,-1,abs)
print(a_value)

10

filter 函数

li = ["Zhejiang","University","City","College"]
def func1(para):
    list1 = []
    for i in para:
        if not i.startswith('C'):
            list1.append(i)
    print(list1)

def func2(para):
    list2 = []
    for i in para:
        if not i.endswith("ty"):
            list2.append(i)
    print(list2)

def filter_test(arg,func1,func2):
    return func1(arg),func2(arg)

li = [2,3,4,5,6]
f = filter(lambda x:x % 2 ==1,li)
print(list(f))

['Zhejiang', 'University']
['Zhejiang', 'College']

功能:

  • 过滤掉序列中不符合函数条件的元素。当序列中需要保留的元素可以用某些函数描述时,就应该想到filter函数。

调用格式:

  • filter(function,sequence)
    • function —> 可以是自定义的函数,也可以是匿名函数
    • sequence —> 列表元组字符串

map 映射

功能:

  • 求一个序列或者多个序列进行函数映射后的值。(用list()强转)

格式:

  • map(function,iterable1,iterable2)
    • function的参数可以不止一个
    • iterable1,iterable2就是传入function的参数
li = [1,2,3,4,5]
res = map(lambda x:x+1,li)
print(list(res))

[2, 3, 4, 5, 6]

x = [1,2,3,4,5]
y = [2,3,4,5,6]
res = map(lambda x,y:x*y+2,x,y)
print(list(res))

[4, 8, 14, 22, 32]

def f(x,y):
    return x*y+2
res = map(f,x,y)
print(list(res))
[4, 8, 14, 22, 32]

reduce 函数

  • 功能
    • 对一个序列进行压缩运算,得到一个value。
    • python2中,reduce()是内置函数,而在python3中,它被移植到functools模块中。
    • from functools import reeduce
  • 格式
    • reduce(function,iterable,[initial])
      • function必须要传入两个参数
from functools import reduce
y = [2,3,4,5,6]
z = reduce(lambda x,y:x+y,y)
print(z)

20

from functools import reduce
y = [2,3,4,5,6]
z = reduce(lambda x,y:x+y,y,100)	#加初始值相当于将初始值放入列表第一位,再进行运算
print(z)

120

apply

功能:

  • pandas 中,应用对象是pandas中的DataFrame或者Series
  • 直接对DataFrame或者Series应用函数
  • 对pandas中groupby之后的聚合对象应用apply

zip

功能:

  • 将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,返回由这些元组构成的对象
  • 长度不一样的时候,以长度短的为准

注:

利用*操作符,与zip相反,进行解压

格式:

zip(iterable1,iterable2,…)

  • iterable -->两个或者多个可迭代序列(字符串,列表,元组,字典)
    • python2返回由元组组成的列表
    • python3返回的是一个对象,如果要得到一个列表,list强转
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
ziptest1 = zip(b,a)
print(list(ziptest1))

[(4, 1), (5, 2), (6, 3)]

star_zip = zip(*ziptest1)
print(list(star_zip))
[(4, 5, 6), (1, 2, 3)]

a = {1:11,2:22}
b = {3:33,4:44}
c = {5:55,6:66}
tp = tuple(c)
print(tp)
print(list(zip(a,b,c)))

(5, 6)
[(1, 3, 5), (2, 4, 6)]	#对字典进行操作时,只会对键进行操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值