Python2——程序結構(條件、循環),函數

程序結構

  • 順序
  • 分支
  • 循環

分支

  • 基本語法:
    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儘量不要包含循環,如果有,建議使用定義函數完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章