程序結構
- 順序
- 分支
- 循環
分支
- 基本語法:
if 條件表達式:
語句1
語句2
語句3
…… - 條件表達式就是計算結果必須爲布爾值的表達式
- 表達式後面的冒號不能少
- 注意if後面出現的語句,如果屬於if語句塊,則必須使用同一個縮進等級
- 條件表達式結果爲True執行if後面的縮進語句塊
#if語句練習
# 生成包含兩個或者是三個漢字的人名
from random import choice,random
name = choice('趙錢孫李周吳鄭王')
condition = random() #random()函數返回[0,1)區間上的隨機數
if condition > 0.5:
name += choice('付玉延邵子凱')
name += choice('國楠陳涵雪玲瑞')
print(condition)
print(name)
雙向分支
if…… else……語句
if 條件表達式:
語句1
語句2
……
else:
語句1
語句2
……
- 雙向分支有兩個分支,當程序執行到if……else……語句時,一定會執行其中一個,也僅執行一個
- 縮進問題,if和else同一個層級,其他語句一個層級
#語句練習
'''
input作用是:
1.在屏幕上輸入括號內的字符串
2.接收用戶輸入的內容並返回到程序中
3.input返回的內容一定是字符串類型
'''
gender=input("請輸入你的性別:")
print("你輸入的性別是:{}".format(gender))
if gender=="男":
print("代碼敲十遍")
else:
print("發糖嘍")
print("開始今天的課程。")
運行結果:
請輸入你的性別:男
你輸入的性別是:男
代碼敲十遍
開始今天的課程。
Process finished with exit code 0
多路分支
好多分支的情況,簡稱多路分支,語法如下:
if 條件表達式:
語句1
……
elif 條件表達式:
語句1
……
……
else:
語句1
……
(elif可以有很多個,else可以沒有)
if語句其他:
- if可以嵌套,但是不推薦
- Python沒有switch-case語句
循環語句
- 重複執行某些固定動作或者處理基本固定的事物
- 分類:for循環,while循環
for循環
語法:
for 變量 in 序列:
語句1
語句2
……
- for循環非常適合用來遍歷容器類對象(list,tuple,dict,set,string以及map,zip等類似對象)中的元素
語法:
for 循環遍歷 in 容器類對象:
循環體
else:
語句塊
# 輸入n個數,然後求出這n個數的平均數
n = eval(input('你想要輸入幾個數:'))
sum = 0
for i in range(n):
x = eval(input('輸入你想輸入的數字>>>'))
sum += x
print("你輸入的{}個數的平均值爲:".format(n),sum/n)
運行結果:
你想要輸入幾個數:4
輸入你想輸入的數字>>>5
輸入你想輸入的數字>>>15
輸入你想輸入的數字>>>85
輸入你想輸入的數字>>>66
你輸入的4個數的平均值爲: 42.75
Process finished with exit code 0
range介紹
- 生成一個數字序列
- 具體範圍可以設定
- 注意,一般在Python中,如果有表示數字範圍的兩個數,一般是包含左邊的數字而不包含右邊的數字
- randint是特例,他左右數字都包含
for-else語句
- 當for循環結束時,執行else語句
- else語句是可選語句
for循環缺點
- 程序開始時必須提供輸入數字的總數
- 大規模數字求平均值需要用戶先數清楚個數
- for循環時需要提供固定循環次數的循環方式
while循環
- 一個循環語句
- 表示當某條件成立時,就循環
- 不知道具體循環次數,但知道循環成立的條件時用while循環
while語法(表示法1):
while 條件表達式:
語句塊
#如果年利率是6.7%,本利是每年翻滾,則多少年以後會翻倍
benqian =100000
year =0
while benqian<200000:
benqian=benqian*(1+0.067)
year +=1
print("第{0}年拿了{1}錢".format(year,benqian))
運行結果:
第1年賺了106700.0錢
第2年賺了113848.9錢
第3年賺了121476.77629999998錢
第4年賺了129615.72031209998錢
第5年賺了138299.97357301068錢
第6年賺了147566.07180240238錢
第7年賺了157452.99861316333錢
第8年賺了168002.34952024528錢
第9年賺了179258.5069381017錢
第10年賺了191268.8269029545錢
第11年賺了204083.83830545243錢
Process finished with exit code 0
while語法(表示法2):
while 條件表達式:
語句塊1
else:
語句塊2
循環保留字continue,break,pass
- break:無條件結束整個循環,簡稱循環猝死
- continue:無條件結束本次循環,重新進入下一輪循環
- pass:表示略過,通常用於佔位,沒有跳過功能
#break語句練習(尋找數字7)
for i in range(1,11):
if i==7:
print('我找到了')
break
else:
print(i)
運行結果:
1
2
3
4
5
6
我找到了
Process finished with exit code 0
#continue語句練習(尋找所有偶數)
for i in range(1,11):
if i%2==1:
continue
print('{}是偶數'.format(i))
運行結果:
2是偶數
4是偶數
6是偶數
8是偶數
10是偶數
Process finished with exit code 0
函數
- 代碼的一種組織形式
- 一個函數一般完成一項特定的功能
- 函數使用
- 函數需要先定義
- 使用函數,俗稱調用
函數定義
def 函數名():
函數語句
return<返回值列表>
- 函數是一段具有特定功能的、可重用的語句組,通過函數名進行功能調用
- 函數也可以看作是一段具有名字的子程序,可以在需要的地方調用執行,不需要每個地方都進行編寫。
函數的參數和返回值
- 參數:負責給函數傳遞一些必要的數據和信息
- 形參(形式參數):在函數定義的時候用到的參數沒有具體的值,只是一個佔位的符號
- 實參(實際參數):在調用函數的時候輸入的值
- 返回值:函數的執行結果
- 使用return關鍵字
- 如果沒有return,默認返回一個None
- 函數一旦執行return語句,則無條件返回,即結束函數的執行
#參數的定義和使用
#參數person只是一個符號,代表的是調用的時候的某一個數據
#調用的時候,會用P的值代替函數中所有的person
def hello(person):
print("{0},你怎麼了?".format(person))
print("{0},愛你呦寶貝".format(person))
p="sunyue"
hello(p)
運行結果:
sunyue,你怎麼了?
sunyue,愛你呦寶貝
Process finished with exit code 0
#九九乘法表
#版本1.0
for row in range(1,10):
for col in range(1,row+1):
print(row*col,end=" ")
print('')
運行結果:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72 81
Process finished with exit code 0
#九九乘法表
#版本2.0
def printline(row):
for col in range(1,row+1):
print(row*col,end=" ")
print('')
for row in range(1,10):
printline(row)
運行結果:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72 81
Process finished with exit code 0
參數詳解
- [參考資料](https://www.cnblogs.com/bingabcd/p/6671368.html)
- python參考資料:headfirst python -> 零基礎入門學習Python(小甲魚) ->
習題 -> 騰訊公開免費課 - 參數分類
- 普通參數
- 默認參數
- 關鍵字參數
- 收集參數
普通參數
- 定義的時候直接定義變量名
- 調用的時候直接把變量或者值放入指定的位置
語法:
def 函數名(變量1,變量2,……)
函數體
#調用
函數名(value1,value2,……)
#調用的時候,具體指參考的是位置,按位置賦值
默認參數
- 形參帶有默認值
- 調用的時候,如果沒有對相應形參賦值,則使用默認值
def fun_name(p1=v1,p2=v2……)
fun_block
#調用1
fun_name()
#調用2
value1=100
value2=200
fun_name(value1,value2)
#默認參數實例
def reg(name,age,gender='male'):
if gender =='male':
print('{0}is {1},and he is a good student'.format(name,age))
else:
print('{0}is {1},and she is a good student'.format(name,age))
reg('zhaojiaxuan',23)
reg('sunyue',23,gender='female')
運行結果:
zhaojiaxuanis 23,and he is a good student
sunyueis 23,and she is a good student
Process finished with exit code 0
關鍵字參數
語法:
def func(p1=v1,p2=v2……)
func_body
調用函數:
func(p1=value1,p2=value2……)
- 比較麻煩,但也有好處:
- 不容易混淆,一般實參和形參按照位置一一對應即可,容易出錯
- 使用關鍵字參數,可以不考慮參數位置
#關鍵字參數案例
#參數可以不按位置存放
def stu_key(name='No name',age=0,addr='No addr'):
print('I am a student')
print('我叫{0},我今年{1}歲了,我家住在{2}'.format(name,age,addr))
n='趙家璇'
a=23
addr='山西'
stu_key(age=a,name=n,addr=addr)
運行結果:
I am a student
我叫趙家璇,我今年23歲了,我家住在山西
Process finished with exit code 0
收集參數
- 把沒有位置,不能和定義時的參數位置相對應的參數,放入一個特定的數據結構中
- 語法:
def func(*args):
func_body
#按照list使用方式訪問args得到傳入的數據
調用:
func(p1, p2, p3……)
- 參數名args不是必須這麼寫,但是,推薦直接用args
- 參數名args前需要有一個星號
- 收集參數可以和其他參數共存
#收集參數案例
#模擬一名學生進行自我介紹,但是具體內容不清楚
#args看作是一個list
def stu(*args):
print('大家好,我自我介紹一下,簡單說兩句:')
print(type(args))
for item in args:
print(item, end=" ")
print('')
stu('趙家璇', 18, '山西')
stu('孫月')
運行結果:
大家好,我自我介紹一下,簡單說兩句:
<class 'tuple'>
趙家璇 18 山西
大家好,我自我介紹一下,簡單說兩句:
<class 'tuple'>
孫月
Process finished with exit code 0
收集參數之關鍵字收集參數
- 把關鍵字參數按照字典格式存入收集參數
- 語法:
def func( **kwargs):
func_body
#調用:
func(p1=v1, p2=v2, .....)
- 調用的時候,把多餘的參數放入kwargs
- 訪問kwargs需要按照字典格式訪問
#收集參數案例
#調用的時候需要使用關鍵字參數調用
def stu( **kwargs):
#在函數體內調用kwargs不用帶星號
print("Hello,大家好,我來自我介紹一下:")
print(type(kwargs))
for a,b in kwargs.items():
print(a, "---", b)
stu(name="zhaojiaxuan", age=23, addr="shangxi", lover="sunyue")
運行結果:
Hello,大家好,我來自我介紹一下:
<class 'dict'>
name --- zhaojiaxuan
age --- 23
addr --- shangxi
lover --- sunyue
Process finished with exit code 0
收集參數混合調用的順序問題
- 收集參數,關鍵字參數,普通參數可以混合使用
- 使用規則就是,普通參數和關鍵字參數優先
- 定義的時候一般找普通參數,關鍵字參數,收集參數tuple,收集參數dict
#收集參數混合調用案例
#stu模擬學生的自我介紹
def stu(name, age, *args, hobby="沒有", **kwargs): #這裏參數的定義與調用順序不可出錯
print("Hello,大家好")
print("我叫{0},我今年{1}歲了。".format(name, age))
if hobby == "沒有":
print("對不起,我沒有愛好。")
else:
print("我的愛好是{}".format(hobby))
print("*" * 20)
for i in args:
print(i)
print("#" * 20)
for k, v in kwargs.items():
print(k, "---", v)
#開始調用
name = "zhaojiaxuan"
age = 23
stu(name, age, "孫月", "這是我喜歡的人", hobby="游泳", major="計算機專業", school="山西財經大學")
運行結果:
Hello,大家好
我叫zhaojiaxuan,我今年23歲了。
我的愛好是游泳
********************
孫月
這是我喜歡的人
####################
major --- 計算機專業
school --- 山西財經大學
Process finished with exit code 0
收集參數的解包問題
- 把參數放入list中,直接把list中的值放入手機參數中
- 語法(參見以下案例)
def stu(*args):
print("哈哈哈")
n=0 #表示循環次數
for i in args:
print(type(i))
print(n)
n +=1
print(i)
l=["zhaojiaxuan", 23, "sunyue", 23]
stu(l) #此時args的表示形式只是tuple內的一個元素,即 args=(["zhaojiaxuan", 23, "sunyue", 23], )
print("-" * 10, "分", "-" * 10, "割", "-" * 10, "線", "-" * 10)
stu(*l) #此時需要對list進行解包,具體操作就是加一個星號
運行結果:
哈哈哈
<class 'list'>
0
['zhaojiaxuan', 23, 'sunyue', 23]
---------- 分 ---------- 割 ---------- 線 ----------
哈哈哈
<class 'str'>
0
zhaojiaxuan
<class 'int'>
1
23
<class 'str'>
2
sunyue
<class 'int'>
3
23
Process finished with exit code 0
- 同理,dict類型收集參數同樣可以解包,但是需要兩個星號(**)進行解包
返回值
- 函數和過程的區別(有沒有返回值)
- 需要用return顯示返回的內容
- 如果沒有返回值,默認返回None
- 推薦寫法,不管有沒有返回值,都以return結束
- 如果是return多個參數,調用函數以後顯示得結果以元組形式輸出。
def func_1():
print("有返回值")
return 1
def func_2():
print("沒有返回值")
f1=func_1()
print(f1)
f2=func_2()
print(f2)
運行結果:
有返回值
1
沒有返回值
None
Process finished with exit code 0
函數文檔
- 函數文檔的作用是對當前函數提供使用相關信息的參考信息
- 文檔的寫法:
- 在函數內部開始的第一行使用三引號字符串定義符
- 一般具有特定格式
- 文檔查看:
- 使用help函數,形如 help(func)
- 使用doc,參看案例
#文檔案例
def func(name, age, addr):
'''
這是該函數的文字文檔
:param name:表示學生的姓名
:param age:表示學生的年齡
:param addr:表示該學生的住址
:return:該函數沒有返回值
'''
print('你好')
help(func)
print("*" * 50)
print(func.__doc__) #此處爲雙下劃線
運行結果:
Help on function func in module __main__:
func(name, age, addr)
這是該函數的文字文檔
:param name:表示學生的姓名
:param age:表示學生的年齡
:param addr:表示該學生的住址
:return:該函數沒有返回值
**************************************************
這是該函數的文字文檔
:param name:表示學生的姓名
:param age:表示學生的年齡
:param addr:表示該學生的住址
:return:該函數沒有返回值
Process finished with exit code 0
變量作用域
- 變量有作用範圍限制
- 分類(按照作用域分類)
- 全局(global):在函數外部定義
- 局部(local):在函數內部定義
- 變量的作用範圍:
- 全局變量:在整個全局範圍內有效
- 全局變量在局部可以使用(即函數內部可以訪問函數外部定義的變量)
- 局部變量:在局部範圍內可以使用
- 局部變量在全局範圍無法使用
- 全局變量:在整個全局範圍內有效
- LEGB原則
- L(local)局部作用域
- E(Enclosing function local)外部嵌套函數作用域
- G(Global module)函數定義所在模塊作用域
- B(Buildin)Python內置模塊的作用域
#案例
#認爲a1是全局變量
a1 = 100
def fun():
print(a1)
print("i am in fun")
#a2的作用範圍是fun
a2=99
print(a2)
print(a1)
fun()
print(a2) #a2是局部變量,外部不能調用
運行結果:
100
100
i am in fun
File "C:/Users/zjx/PycharmProjects/untitled/2.py", line 12, in <module>
99
print(a2)
NameError: name 'a2' is not defined
Process finished with exit code 1
提升局部變量爲全局變量
- 使用global
- 案例如下
b1=90
def fun():
global b1 #將函數內的b1提升爲全局變量,覆蓋原來的b1值
b1=100
print("函數內修改後b1=",b1)
print("初始值b1=",b1)
fun() #運行函數後值纔會發生改變,否則b1的值還是90
print("運行完函數後b1=",b1)
運行結果:
初始值b1= 90
函數內修改後b1= 100
運行完函數後b1= 100
Process finished with exit code 0
globals,locals函數(內建函數)
- 可以通過globals和locals函數顯示出局部變量和全局變量
- 參看案例
#案例
a=1
b=2
def fun(c,d):
e=111
print("Locals={0}".format(locals()))
print("Globals={0}".format(globals()))
fun(100,200)
運行結果:
locals={'c': 100, 'd': 200, 'e': 111}
globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000001640B06080>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/zjx/PycharmProjects/untitled/2.py', '__cached__': None, 'a': 1, 'b': 2, 'fun': <function fun at 0x0000001640ABC1E0>}
Process finished with exit code 0
eval()函數
- 把一個字符串當作一個表達式來執行,返回表達式執行後的結果
- 語法:
eval(string_code, globals=None, locals=None)
#eval()語法案例
x=100
y=200
#執行z=x+y
z1=x+y
z2=eval("x+y")
print(z1)
print(z2)
運行結果:
300
300
Process finished with exit code 0
exec()函數
- 與eval()函數功能類似,但是不返回結果
- 語法:
exec(string_code, globals=None, locals=None)
#exec()語法案例
x=100
y=200
#執行z=x+y
z1=x+y
#注意字符串中雙引號的寫法
z2=exec("print('x+y:',x+y)")
print(z1)
print(z2)
運行結果:
x+y: 300
300
None
Process finished with exit code 0
遞歸函數
- 函數直接或者間接調用自己
- 優點:簡潔,容易理解
- 缺點:對遞歸深度有限制,消耗資源大
- Python對遞歸深度有限制,超過限度會報錯
- 在寫遞歸程序的時候,一定要注意結束條件
#斐波那契數列
def fib(n): #n表示第n個數字的斐波那契數列的值
if n==1:
return 1
if n==2:
return 1
return fib(n-2)+fib(n-1)
print(fib(7))
運行結果:
13
Process finished with exit code 0
'''字符串反轉'''
# 方法1:字符串轉換爲一個列表,然後列表反轉,最後列表迴轉爲字符串
def reverseStr(s):
ls = list(s)
ls.reverse()
s = "".join(ls) #將列表整合爲一個字符串
print(s)
str = 'sioujtnjg 1563'
reverseStr(str)
#方法2:遞歸
#1.將字符串分割爲首字母和剩餘部分
#2.將剩餘部分進行反轉,然後末尾加上首字母
def reverseStr_new(s):
if len(s) <= 0:
return ""
else:
return reverseStr_new(s[1:]) + s[0]
str1 = "oiejtgg f57946"
print(reverseStr_new(str1))
結果:
3651 gjntjuois
64975f ggtjeio
Process finished with exit code 0
Lambda匿名函數
- 匿名函數並非沒有名字,而是將函數名作爲函數結果返回,如下:
- <函數名> = lambda <參數列表> : <表達式>
- 等價於:
def <函數名>(<參數列表>):
return <表達式>
lambda函數特點
- lambda函數大量簡化了代碼,使代碼簡練清晰。但是會降低代碼的可讀性。
- lambda並不會帶來程序運行效率的提高,只會使得代碼更加簡潔。
- 如果可以使用for……in……if完成,儘量不要使用lambda
- lambda儘量不要包含循環,如果有,建議使用定義函數完成。