例題引導:
【模拟輪盤抽獎遊戲】
輪盤分為三部分: 一等獎, 二等獎和三等獎;輪盤轉的時候是随機的,獎項設定如下:如果範圍在[0,0.08)之間,代表一等獎,如果範圍在[0.08,0.3)之間,代表2等獎,如果範圍在[0, 1.0)之間,代表3等獎,
要求:假設本次活動1000人參加, 模拟遊戲時各等級獎品個數需要準備多少個。
解題思路:定義遊戲規則(用字典表達)-建構函數-生成随機數-編寫遊戲邏輯-調用函數-周遊1000名使用者-列印輸出
參考答案:
import random #導入随機數子產品
rewardDict = {
'一等獎': (0, 0.08),
'二等獎': (0.08, 0.3),
'三等獎': (0.3, 1)
} #因為該值為一對一映射,是以想到用字典定義得獎範圍
def rewardFun(): #開始建構函數
"""使用者得獎等級"""
# 生成一個0~1之間的随機數
num = random.random()
# 判斷随機轉盤轉的數是幾等獎
for k, v in rewardDict.items():
# 這裡的v是元組
if v[0] <= num < v[1]:
return k
# print rewardFun()
resultDict = {}
for i in range(1000):
# res:本次轉盤的等級(一/二/三等獎)
res = rewardFun() #調用函數
if res not in resultDict:
resultDict[res] = 1
else:
resultDict[res] = resultDict[res] + 1
for k, v in resultDict.items():
print k, '---------->', v
複制
學習引導:
- 函數概念
- 函數定義
- 函數調用
- 參數調用
- 參數傳遞
函數的概念
函數是将具有獨立功能的代碼塊組織成為一個整體,使其具有特殊功能的代碼集。它是編輯好的、可直接調用的、可重複使用的,用來實作單一或相關聯功能的代碼段
優點:
- 提高程式的子產品性;
- 使程式變得可擴充;
- 減少重複代碼;
- 使程式變得可維護;
函數的定義
函數必須先建立才可以使用,該過程稱為函數定義,使用函數的過程稱為函數調用。
函數可以根據自己的需求來定義,但有一些規則需要注意:
- 函數代碼塊必須以def開頭,後接函數辨別符名稱和圓括号();
- 任何傳入參數和自變量必須放在圓括号中間,圓括号之間可以用于定義參數;
- 函數的第一行語句可以選擇性的使用文檔字元-用于存放函數說明;
- 函數内容以冒号起始,并且縮進;
- 函數名稱的命名應符合辨別符的命名規則;(可由字母、下劃線和數字組成;不能以數字開頭;不能與關鍵字重名)
- return[表達式]結束函數,選擇性地傳回一個值給調用方。不帶表達式的return相當于傳回None
函數定義的一般格式:
#函數定義的一般格式:
def 函數名 (參數清單):
函數體
複制
#執行個體1
def hello():
print('Hello World')
hello()
複制
#Hello World
複制
執行個體2-計算圓的面積,帶參數
#執行個體2-計算圓的面積,帶參數
def area(r):
pi=3.412
return pi*(r^2)
r=5
print('圓的面積為:',area(r))
複制
#圓的面積為: 23.884
複制
函數調用
即使用函數的過程
簡單的調用應用
#函數功能:列印該字元串
def println(str):
print(str)
return
#調用函數
println('調用上述函數')
println('列印這段字元串')
println('多次調用函數')
複制
#調用上述函數
#列印這段字元串
#多次調用函數
複制
參數調用
參數分為形參、實參
- 形參:函數定義時括号内的參數
- 實參:函數調用時括号内的參數
- 形參相當于變量,實參相當于變量的值
在實際代碼中表示如下:
#定義時:
def func(a,b,c):
pass
其中 a,b,c 為形參
#調用時:
func(1,2,3)
其中1,2,3為實參
複制
形參:
隻在被調用時,才配置設定存儲單元。調用結束,立刻釋放所配置設定的記憶體。
形參隻在函數内部有效
實參:
可以是:常量、變量、表達式、函數
進行函數調用時,實參必須是确定的值
位置參數:
- 位置形參:函數定義時,從左往右寫的參數,比如上面的 a, b , c
- 位置實參:函數調用時,從左往右寫的參數, 比如上面的 1,2,3
- 位置形參定義多少個,調用時位置實參必須寫上多少個,多一個少一個都不行。
- 位置參數必須以正确的順序傳入函數。調用時的數量必須和聲明時的一樣。
def func(a,b,c):
return a+b+c
#調用
print(func(2,3,4))
複制
#9
複制
錯誤示範:
def func(a,b,c):
return a+b+c
#調用
print(func(2,3)) #實參數量不對應,報錯
複制
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-21-38b482e25fef> in <module>
3
4 #調用
----> 5 print(func(2,3))
TypeError: func() missing 1 required positional argument: 'c'
複制
關鍵參數:
- 正常情況下,給函數傳參數,要按順序。如果不想按順序,就用關鍵參數。
- 指定參數名的參數,就叫做關鍵參數。
- 函數調用時:func(a=1, b=2), 這種指定了參數名的參數,就是關鍵參數。
- 調用函數時,關鍵參數可以和位置參數一起用,但是關鍵參數必須在位置參數的後面。不然會報錯。
def func(a,b,c):
return a+b+c
#調用
print(func(4,c=3,b=2))
複制
#9
複制
預設參數:
- 函數定義時,預設參數必須在位置形參的後面。
- 函數調用時,指定參數名的參數,叫關鍵參數。
- 而在函數定義時,給參數名指定值的時候,這個參數叫做預設參數。
-
關鍵參數,和預設參數兩個參數寫法一樣,差別在于:
關鍵參數是在函數調用時,指定實參的參數名,也可以說指定值的參數名。
預設參數是在函數定義時,指定參數名的值。
-
寫法:
def (a, b=100): pass
- 定義時,有預設參數的話,調用時,這個實參可以不寫。如果實參不寫的話,這個形參的參數值是他的預設值。
執行個體示範:
def info(name,age=18):
print('名字:',name)
print('年齡:',age)
return
#調用
info(age=22,name='Jack')
print('****************')
info(name='Jack')
複制
'''
名字: Jack
年齡: 22
*****************
名字: Jack
年齡: 18
'''
複制
動态參數:* args ** kwargs
當你需要一個函數能處理很多參數,超過已聲明的參數數量,這時就需要動态參數。與上述兩中參數不同的是,該參數聲明不需要命名。
* args
一個'* '的參數會以元組(tuple)的形式導入,存放未命名的變量參數
#函數定義
def printinfo(arg1,*vartuple):
print('輸出:')
print(arg1)
print(vartuple)
#調用
printinfo(34,45,32,12)
複制
#輸出:
#34
#(45, 32, 12)
複制
如果函數調用時沒有指定參數,動态參數則表現為空元組。
#函數定義
def printinfo(arg1,*vartuple):
print('輸出:')
print(arg1)
print(vartuple)
#調用
printinfo(34)
複制
#輸出:
#34
#()
複制
** kwargs
還有一種動态參數,加了兩個星号則以字典的形式導入
#函數定義
def printinfo(arg1,**vardict):
print('輸出:')
print(arg1)
print(vardict)
#調用
printinfo(34,a=45,b=32,c=12)
複制
#輸出:
#34
#{'a': 45, 'b': 32, 'c': 12}
複制
聲明函數時,參數中的* 可以單獨出現。
如果* 單獨出現,後面的參數必須以關鍵字傳入
def func(a,b,*,c):
return a+b-c
func(3,2,4) #非關鍵字傳入報錯
複制
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-34-f69556d382a4> in <module>
2 return a+b-c
3
----> 4 func(3,2,4)
TypeError: func() takes 2 positional arguments but 3 were given
複制
關鍵字傳入正确
func(3,4,c=5)
複制
#2
複制
參數傳遞
python語言中,類型屬于對象,變量是沒有類型的,例如:
a=[1,2,3]
a='DataScience'
其中[1,2,3]是list類型,'DataScience'是string類型,變量a沒有類型,它隻是一個對象的引用(一個指針),可以指向list類型對象也可以指向string類型對象
可更改(mutable)與不可更改(immutable)對象
在 python 中,strings, tuples, 和 numbers 是不可更改的對象,而 list,dict 等則是可以修改的對象。
- 不可變類型:變量指派 a=5 後再指派 a=10,這裡實際是新生成一個 int 值對象 10,再讓 a 指向它,而 5 被丢棄,不是改變a的值,相當于新生成了a。
- 可變類型:變量指派 la=[1,2,3,4] 後再指派 la[2]=5 則是将 list la 的第三個元素值更改,本身la沒有動,隻是其内部的一部分值被修改了。
python 函數的參數傳遞:
- 不可變類型:類似 c++ 的值傳遞,如 整數、字元串、元組。如fun(a),傳遞的隻是a的值,沒有影響a對象本身。比如在 fun(a)内部修改 a 的值,隻是修改另一個複制的對象,不會影響 a 本身。
- 可變類型:類似 c++ 的引用傳遞,如 清單,字典。如 fun(la),則是将 la 真正的傳過去,修改後fun外部的la也會受影響
python 中一切都是對象,嚴格意義我們不能說值傳遞還是引用傳遞,我們應該說傳不可變對象和傳可變對象。
#傳不可變對象執行個體
#
#函數定義
def changeInt(a):
a=10
#函數調用
b=5
changeInt(b)
print(b)
複制
#5
複制
執行個體中有 int 對象 2,指向它的變量是 b,在傳遞給 ChangeInt 函數時,按傳值的方式複制了變量 b,a 和 b 都指向了同一個 Int 對象,在 a=10 時,則新生成一個 int 值對象 10,并讓 a 指向它。
#傳可變對象執行個體
def changelist(List):
#對傳入的清單進行擴充
List.append([1,2,3,4])
print('函數内取值:',List)
return
#函數調用
List=['datascience']
changelist(List)
print('函數外取值:',List)
複制
#函數内取值: ['datascience', [1, 2, 3, 4]]
#函數外取值: ['datascience', [1, 2, 3, 4]]
複制
可變對象在函數裡修改了參數,那麼在調用這個函數的函數裡,原始的參數也被改變了。
傳入函數的和在末尾添加新内容的對象用的是同一個引用。
小作業
1.構造一個describe_pet函數,調用該函數輸入以下2隻寵物的資訊:
I have a cat. My cat's name is Monkey.
I have a lizard. My lizard's name is Cola.
2.編寫函數, 接收一個清單(包含10個整形)和一個整形k, 傳回一個新清單,要求: - 将清單下标k之前對應(不包含k)的元素逆序; - 将下标k及之後的元素逆序;
3.請用函數實作一個判斷使用者輸入的年份是否是閏年的程式
4.構造一個greeting函數,調用函數并使用循環,對輸入的參數傳回整理後的greeting資訊。
例如,在控制台分别輸入名字“Mary”和姓“Chen”,調用函數後輸出"Hello, Mary Chen!",并提示輸入下一組姓和名。直到控制台輸入姓或名為“end”時,程式結束。