遞迴函式就是在函式內部呼叫自身的函式,如階乘 n! ,用 fact(n)表示
def fact
(n) if n == 1:
return 1
return n * fact
(n - 1)
遞迴函式的定義簡單,邏輯清晰,理論上所有遞迴函式都可以改寫為迴圈的方式,但是迴圈的邏輯不如遞迴函式清晰。
使用遞迴函式時,需要防止棧溢位,因為在計算機中, 函式的呼叫是通過 棧 這種資料結構來實現的,每次呼叫乙個函式,棧就會加一層棧幀,當函式返回時減一層,由於棧的大小有限,所以遞迴函式呼叫次數過多,就會出現棧溢位。
>>> fact
(1000)
traceback (most recent call last)
: file "", line 1, in file "", line 4, in fact
...file "", line 4, in fact
runtimeerror
: maximum recursion depth exceeded in comparison
可以通過 尾遞迴優化 來解決這個問題,尾遞迴就是返回的值裡面沒有表示式,我們可以考慮用另乙個函式 fact_iter(num,product) 。 product 用來儲存 n-1 之前所有的乘積
def fact_iter
(num,product)
: if num == 1:
return product
return fact_iter
(num-1,n*product)
def fact
(n) return fact_iter
(n,1)
由於num-1 和 n*product 在呼叫函式前就已經被計算,所以不影響函式呼叫。
如果針對尾遞迴做了優化,棧就不會增長,也就不會溢位,但是對於大多數語言沒有針對尾遞迴做優化,所以還是會棧溢位。
漢諾塔的移動可以用遞迴函式非常簡單地實現。
請編寫move(n, a, b, c)函式,它接收引數n,表示3個柱子a、b、c中第1個柱子a的盤子數量,然後列印出把所有盤子從a借助b移動到c的方法,例如:
需要的是借助b把所有盤子從a移到c,對於n個盤子,需要先把最底下那個移到c,首先需要把n-1個盤子移動到b,再把最大的盤子從a移動到c,再把n-1個盤子移動到a,之後開始迭代
# -*- coding: utf-8 -*-
defmove
(n, a, b, c)
:
#方法一
if n ==1:
print
(a,'-->'
, c)
return
move(n -
1, a, c, b)
print
(a,'-->'
, c)
move(n -
1, b, a, c)
return
#方法二
if n ==1:
print
(a,'-->'
, c)
else
: move(n -
1, a, c, b)
print
(a,'-->'
, c)
move(n -
1, b, a, c)
# 期待輸出:
# a --> c
# a --> b
# c --> b
# a --> c
# b --> a
# b --> c
# a --> c
move(3,
'a',
'b',
'c')
初學Python第五天
繼上次10.3賦值運算子之後 4 位運算子 定義 把數字看做二進位制進行計算的運算子。例如 1 按位 與 運算子 只要兩個對應的二進位制位有乙個為0,則該位結果為0,否則為1 60 13 輸出結果12,二進位制解釋 00001100。2 按位 或 運算子 只要兩個對應的二進位制位有乙個為1,則該位結...
2020 3 15初學python第五天
字典dict 不是序列,用大括號括起來,體現對映關係,由鍵和值組成。如 訪問字典的方法 keys 返回字典所有的鍵 values 返回字典所有的值 items 把每乙個項 剪 值 以元組的形式列印出來 clear 清空乙個字典 update 更新字典 等 集合set 用大括號括起來,不反映對映關係,...
Python第五天 迭代,函式
1.實現迭代協議的資料型別可迭代遍歷 2.可迭代物件 實現了 inter 方法的物件就叫做可迭代物件 3.迭代器 實現了 iter 和 next 方法的物件就是迭代器 4.list等有索引的可迭代物件會將所有內容載入到記憶體,比較耗費記憶體,其他可迭代物件只將部分內容載入到記憶體 5.內建可迭代物件...