天天看點

函數式程式設計函數函數傳遞和引用

函數

  • 函數定義:

    函數是一段有特定功能、可以重複使用的代碼。

  • 函數基本文法:

    def functionName(paraments): 以def開頭

    “”"函數文檔字元串”“” 用以說明函數用途

    function suite

    return [expression] 結束函數,傳回一個值給調用方,不帶表達

    式的return相當于傳回None

  • 函數調用基本文法:

    [傳回值] = 函數名[(形參值)]

def testDemo(demo):
	re = demo + 1
	return re
re = testDemo(1)
print(re)
           

函數傳遞和引用

  • 形式參數:定義函數時,函數名後面括号中的就是形參
  • 實際參數:調用函數時,函數名後面括号中的就是實參,也就是調用方給

    函數的參數

def testDemo(demo):   #形參
	re = demo + 1
	return re
re = testDemo(1)	 #實參
print(re)
           

可變參數和不可變參數

  • 不可變參數

    整數、字元串、元組

  • 可變參數

    字典、清單

ef changetuple(tu):
	tu = (1,2,3,4)
	print('體内',tu)
tu = (1,2,3,5)
changetuple(tu)
print(tu)

def testList(li1):
	li1.append(2)

	print('内',li1)
li1 = [1,2,3]
testList(li1)
print('外',li1)
           

函數參數

#位置參數,根據位置比對
def fun_a(a,b):
	print('a={},b={}'.format(a,b))
fun_a(1,2)

#關鍵字參數,根據參數名比對
def fun_a(a,b):
	print('a={},b={}'.format(a,b))
fun_a(b=1,a=2)

#預設參數,有傳參使用傳參,不傳值使用預設值,
def fun_a(a,b,c='test'):
	print('a={},b={},c={}'.format(a,b,c))
fun_a(a='he',b=2)
fun_a(1,2,3)

#可變參數(不定長參數)
#*a代表元組參數,**b代表字典參數
def fun_b(*a,**b):
	print('a={},b={}'.format(a,b))
fun_b(10,11,12,name='sz',age=28)
           

return函數

return語句指定傳回值可以是任意類型,return語句可以在同一函數中出現多次,有一個return被執行,剩下的都不會被執行

文法:return [傳回值]

傳回值參數不寫時傳回空值None

def add(a,b):
	c = a + b
	return a,b,c
def add1():
	x,y,z = add(10,20)
	print(x,y,z)
add1()
           

變量作用域

  • 全局變量

    在所有函數外部定義的變量稱為全局變量,作用域是整個程式,既可以在函數内部使用也可以在函數外部使用

  • 局部變量

    在函數内部定義的變量稱為局部變量,作用域是函數内部

#局部變量
def funa():
	fun_str = '内部函數'
	print('函數體内:',fun_str)
funa()
#外部調用報錯
#print(fun_str)

#函數參數,從外部傳入的實參隻能在函數内部生效
def funb(name,age):
	print('{}的年齡是{}'.format(name,age))
funb('小明',18)
#外部調用報錯
#print(name,age)

#全局變量
test1 = 'hello'
def func():
	print('函數體内:',test1)
func()
print('函數體外:',test1)

#global在函數體内申明全局變量
def fund():
	global fun
	fun = 'all_in'
	print('函數體内:',fun)
fund()
print('函數體外:',fun)
           

擷取指定作用域範圍中的變量

  • globals()函數

    傳回一個包含全局範圍内所有變量的字典,鍵為變量名,值為變量值

    列印全局變量print(globals())

    列印某個全局變量的值print(globals()[‘demo’])

  • locals()函數

    傳回一個包含目前作用域内所有變量的字典

    列印局部變量print(locals())

    列印某個局部變量的值print(locals()[‘test’])

  • vars()函數

    傳回類中所有變量的字典,不加object參數和locals()作用一緻

    print(vars())

#globals()可以修改局部變量的值
#locals()在函數體内擷取的是局部變量,在函數體外擷取的是全局變量
#不調用函數時locals()一直擷取不到局部變量的值
kind = 'cook'
def testkind():
	food = 'pook'
	print(locals())
	globals()['food'] = 'beef'
testkind()
print(globals()['kind'])
print(locals())

#gloabls()列印出來是字典,通過for循環周遊出來裡面的值
for k,v in dict(globals()).items():
	print(k,v)
class test2:
	name="李四"
	age=19
print(vars(test2))	
           

局部函數用法(nonlocal)

含義:函數體内定義函數稱之為局部函數

#局部函數,在外層函數調用局部函數
def funa():
	def funb():
		print('www.test.com')
	funb()
funa()
#将局部函數作為外層函數的傳回值,可以擴大局部函數的作用域
def funa():
	age = 10
	def funb():
		name = '張三'
		print('{}的年齡時{}'.format(name,age))
	return funb()
func = funa() #類似于func=funb
func()

#局部函數有同名函數,會發生遮蔽,需要用nonlocal關鍵字申明
#在定義同名變量之前先列印或造成遮蓋的問題
def outdef():
	name = 'zhangsan'
	def indef():
		nonlocal name
		print(name)
		name = 'lisi'
	indef()
outdef()
           

匿名函數用法(lambda)

不給函數起名稱的函數叫匿名函數

文法:變量名=lambda 參數:表達式

參數可選,以逗号分隔

表達式不能包含循環return,可以包含if……else……

優勢:省去定義函數的過程;單次使用邏輯簡單可以使用匿名函數

def funa():
	return 1==2
	print(funa())
a = lambda:1==2
print(funa())

b=lambda x,y,z:x+y+z
print(b(1,3,4))

d = lambda x,y: x==y
e = d(1,2)
print(e)
           

遞歸函數

含義:函數調用函數本身的函數是遞歸函數,遞歸函數由基礎部分和遞歸部分組成

"""
階乘
1!=1*1
2!=1*2		  2!=1!*2
3!=1*2*3     3!=2!*3
4!=1*2*3*4    4!=3!*4
5!=1*2*3*4*5  5!=4!*5
n=(n-1)*n
"""

def fun_a(n):
	if n == 1:
		return n
	n = fun_a(n-1) * n
	return n
re = fun_a(5)
print(re)

"""
斐波那契數列
0
1
1
2
3
5
8
13
21
34
n > = 3
fn = (n-1)+(n-2)
"""
def testdemo(n):
	if n <= 2:
		v = 1
		return v
	v=testdemo(n-1)+testdemo(n-2)
	return v
m = testdemo(6)
print(m)
           

高階函數

函數對象作為參數傳遞給函數或者函數對象作為函數的傳回值叫做高階函數,即函數的函數

  • 函數式程式設計 map()

    文法:map(function,iterable)

    傳入一個函數和一個可疊代對象

#幂函數
def square(x):
	return x**2	
#清單
list1 = [1,2,3,4]
#用map進行幂計算
map1 = map(square, list1)
#map傳回的是一個疊代器
print(map1)
#轉換成list
map_list = list(map1)
print(map_list)

#規範命名,首字母大寫,其餘小寫
list2 = ['MIKE', 'anna', 'WiNg', 'diNa']
#匿名函數
#寫法一
map2 = map(lambda x: x[:1].upper() + x[1:].lower(), list2)
map_list2 = list(map2)
print(map_list2)
#寫法二
def name(y):
	return y[:1].upper() + y[1:].lower()
map3 = map(name, list2)
map_list3 = list(map3)
print(map_list3)

#傳入多個可疊代對象,長度不一緻,取最短的

list_l = [1,2,3,4,5,6]
list_s = [1,4,5]
def add(x,y):
	return x+y
map4 = map(lambda x,y:x+y,list_l,list_s)
# map4 = map(add,list_l,list_s)
map_list4 = list(map4)
print(map_list4)
           
  • filter()函數

    文法:filter(function,iterable)

    由函數和可疊代對象組成,iterable中的每個元素都需要給function判斷,最後所有傳回true的組成一個新的可周遊的集合

def jishu(x):
	return x%2!=0
list1 = [1,2,3,4,5,6,7,8,9]
# filter1 = filter(lambda x:x%2==0,list1)
filter1 = filter(jishu,list1)
list_filter = list(filter1)
print(list_filter)
           
  • reduce()函數

    文法:reduce(function.iterable)

    function函數必須包含兩個參數,iterable表示一個可疊代對象

    對集合做一些累積操作

#需要先導入functools子產品
import functools

sentences = ['The Deep Learning textbook is a resource intended to help students and practitioners enter the field of machine learning in general and deep learning in particular. ']

#統計元素出現的次數
count1 = functools.reduce(lambda x,y:x+y.count('and'),sentences,0)
print(count1)

#對元素進行相加
def add(x, y):
    return x + y
list1 = [1, 2, 3, 45, 1]
# reduce1 = functools.reduce(add, list1)
reduce1 = functools.reduce(lambda x,y:x+y,list1)
print(reduce1)

           

zip()函數

文法:zip(iterable)

将可疊代對象作為參數,把參數打包成一個個元組,然後再把元組組成一個清單

zip(*iterable)把元組解壓成清單

a = [1,2,3]
b = [4,5,6,9,1]
c = [7,8,9,0]
d = zip(a,b,c)
e = list(d)
print(e)
f = zip(*e)
f1 = list(f)
print(f1)