馬山要期末考試了,又要開始卑微的學習了
遞歸的使用
- 遞歸函數的書寫,踩坑: 函數語句中都會有if else 語句中,每句都有return,如果if語句中沒有return,起步遞歸將返回None;如果else語句中沒有return語句,遞歸將會返回None
"""
遞歸
"""
def function1(number): # 非遞歸函數,求階乘
result = 1
for i in range(1, number + 1):
result = i * result
return result
def function2(number): # 遞歸函數,求階乘
if number == 1:
return 1
else:
return number * function2(number - 1) # return必須有,否則返回None,你知道爲什麼嗎??
n = int(input("請輸入一個數:"))
print("%d的階乘是%d" % (n, function1(n))) # 6的階乘是720
print('%d的階乘是%d' % (n, function2(n))) # 6的階乘是720
斐波那契數列的遞歸與迭代書寫
斐波那契數列的遞歸書寫:
- 可以看出,遞歸書寫更加符合斐波那契數列函數以及人類的思維
- 遞歸可以使代碼簡潔,可讀性增加,但同時也會增加時間 空間的複雜度
def f1(n):
if n == 1:
return 1
elif n == 2:
return 1
else:
return f1(n - 1) + f1(n - 2)
print(f1(12)) # 144
斐波那契數列的迭代書寫:
- 利用迭代的思想可以完成斐波那契數列的書寫,但理解起來需要下一番功夫
- 合理運用遞歸操作在以後的代碼生涯是非常必要的
def f2(n):
n1 = 1
n2 = 1
n3 = 1
while (n - 2) > 0:
n3 = n2 + n1 # n3在這裏沒啥實際意義,就是爲了完成下面n1 n2 的賦值操作
n1 = n2
n2 = n3
n -= 1
print(n)
if n == 1:
return n1
else:
return n2
print(f2(12)) # 144
運用遞歸完成漢諾塔問題
漢諾塔是一種益智玩具,源自古老的印度。如圖1、圖2及圖3所示,有三根柱子,若干個大小不等的圓盤按順序依次疊落在起點(左側)的柱子上,通過多次移動後,全部圓盤要疊落在終點(右側)的柱子上。移動必需遵守兩個原則:
- 每次只能移動一個圓盤
- 移動過程中,大圓盤不允許覆蓋在小圓盤上。
def h(n, x, y, z):
if n == 1:
print(x, '--->', z)
else:
h(n - 1, x, z, y) # 這一步可以理解爲先把n-1層移動到y柱
print(x, '--->', z) # 在上一步的基礎上,把最大的那個從x柱移動到z柱
h(n - 1, y, x, z) # 以上兩步的基礎上,發現跟n層的變化就是起始位置x柱變成了y柱,故,將y柱與x柱變換
唯一的映射類型 —— 字典
- 字典是鍵 值的組合,屬於Python中唯一的映射類型
- 可以利用可迭代序列(iterable)和遍歷賦值 來創建字典
- 可以利用可迭代序列(iterable)構成的映射關係來創建字典
- 利用工廠函數dict() 關鍵字參數來創建字典
- 根據鍵對字典進行修改時,如果字典中沒有指定的 鍵 ,則會直接增加一對鍵值對
d = {} # 創建空字典
d1 = dict()
print(d)
print(d1)
dict1 = {'name': "cc雪影", 'sex': '男', 'age': '21'} # 創建非空字典
print(dict1['name'], dict1['age'])
iterable = ((1, 'one'), (2, 'two')) # 利用可迭代序列構成的
for k, v in iterable:
d[k] = v
print(d)
dict2 = dict(((1, 'one'), (2, 'two'), (3, 'three'))) # 利用元組或列表構成映射關係(maping)來創建字典
print(dict2) # dict2: {1: 'one', 2: 'two', 3: 'three'}
dict3 = dict(name='cc雪影', sex='男', age='21') # 用關鍵字參數來創建字典
print(dict3) # dict3: {'name': 'cc雪影', 'sex': '男', 'age': '21'}
print(dict3['name']) # cc雪影
dict3['name'] = '老王' # 字典值的修改 dict3: {'name': '老王', 'sex': '男', 'age': '21'}
dict3['heigh']='187cm' # 字典鍵值對的修改 {'name': '老王', 'sex': '男', 'age': '21', 'heigh': '187cm'}
字典的常用方法
- fromkeys(iterable,value),創建字典,而且不會在原有字典的基礎上修改,而是直接創建一個新的字典
- keys() 以列表的形式(並非直接的列表,若要返回列表值還需調用list函數)返回字典所有的鍵
- values() 以列表的形式(並非直接的列表,若要返回列表值還需調用list函數)返回字典所有的值
- items() 以列表的形式(並非直接的列表,若要返回列表值還需調用list函數)返回字典所有可遍歷的(鍵, 值) 元組數組
- get() 可以根據鍵來獲取 值,也可以根據鍵對來獲取 值,如果字典中不存在該鍵值對,則自動增加並返回 值
- in 與 not in 用來判斷 鍵 是否在字典裏,返回值爲Bool類型
- copy() 淺copy,不同與賦值,淺copy是將字典複製產生新的字典
- popitem() 隨機彈出(鍵,值),可以進行賦值,會改變原字典
- pop() 根據 鍵 彈出 值,可以進行賦值,會改變原字典
- setdefault() 給字典增加鍵值對
- update() 將字典併入字典中,dict.update(dict)
- clear() 清空字典
dict0 = {}
dict1 = dict0.fromkeys((1, 2, 3)) # dict1: {1: None, 2: None, 3: None}
dict2 = dict0.fromkeys((1, 2, 3), "hello") # dict2:{1: 'hello', 2: 'hello', 3: 'hello'}
dict3 = dict0.fromkeys((1, 2, 3), ('one', 'two', 'three'))
# dict3: {1: ('one', 'two', 'three'), 2: ('one', 'two', 'three'), 3: ('one', 'two', 'three')}
dict2 = dict2.fromkeys((1, 3), 'hi') # 重新創建一個新的字典 {1: 'hi', 3: 'hi'}而不是在原有字典的基礎上修改,
dict4=dict0.fromkeys(range(6),'牛') # {0: '牛', 1: '牛', 2: '牛', 3: '牛', 4: '牛', 5: '牛'}
for eachKey in dict4.keys(): # 打印 鍵
print(eachKey,end=' ') # print: 0 1 2 3 4 5
for eachValue in dict4.values(): # 打印 值
print(eachValue,end=' ') # print: 牛 牛 牛 牛 牛 牛
for eachItem in dict4.items(): # 打印 象
print(eachItem,end=' ') # print: (0, '牛') (1, '牛') (2, '牛') (3, '牛') (4, '牛') (5, '牛')
print(dict4.get(5)) # 牛
print(dict4.get(4,'牛')) # 牛
print(dict4.get(6,"B")) # B
print(dict4) # dict4: {0: '牛', 1: '牛', 2: '牛', 3: '牛', 4: '牛', 5: '牛'}
print(4 in dict4) # 查找的是鍵而不是值,打印的是 True
a=dict4.copy() # 淺copy,把子字典複製後讓 a 管理
b=dict4 # 賦值操作,dict4 和 b 共同管理字典{0: '牛', 1: '牛', 2: '牛', 3: '牛', 4: '牛', 5: '牛'}
print('id(a):',id(a)," ",'id(b):',id(b)," ",'id(dict4):',id(dict4))
str1=dict4.popitem() # 隨機彈出一個像,可以進行賦值 str1='(5, '牛')'
str2=dict4.pop(1) # pop()根據 鍵 彈出 值,可以進行賦值 str2='牛'
print(dict4) # dict4: {0: '牛', 2: '牛', 3: '牛', 4: '牛'},可以看出popitem(),pop()均會改變原字典
dict4.setdefault(7) # {0: '牛', 2: '牛', 3: '牛', 4: '牛', 7: None}
dict4.setdefault(8,'贊贊贊') # {0: '牛', 2: '牛', 3: '牛', 4: '牛', 7: None, 8: '贊贊贊'}
dict5={7:'update'}
dict4.update(dict5) # dic4: {0: '牛', 2: '牛', 3: '牛', 4: '牛', 7: 'update', 8: '贊贊贊'}
dict4.clear() # 清空字典 dict4: {}
我們熟悉的 集合
- 集合的唯一性:集合的元素不重複
- 集合的無序性:不可以通過索引來獲取元素
- in , not in 可以用來判斷元素是否在集合中
- add() 增加集合的元素
- remove() 去除集合中指定的元素
- frozen() 不可變集合,沒有add() remove()
num1 = {1, 2, 3} # 創建一個集合
num2 = set([1, 2, 3]) # 利用set工廠函數創建集合,參數是一個可迭代序列(iterable)
num3 = {1, 3, 4, 2, 1} # 集合的唯一性,num2: {1, 2, 3, 4} 注:集合是無序的
print(num2)
# 關於去除列表中重複元素的兩種常見方法
# 1、使用遍歷去除列表重複的元素
list1 = [1, 3, 4, 3, 4, 2, 1, 3, 0, 1]
list2 = []
for each in list1:
if each not in list2:
list2.append(each)
print(list2) # [1, 3, 4, 2, 0]
# 2、利用集合元素唯一性去除列表重複的元素
list3 = list1.copy()
set1 = set(list3)
list4 = list(set1)
print(list4) # [0, 1, 2, 3, 4]
# 判斷元素是否在集合中 in 、not in
print(1 in set1)
print('1'in set1)
set1.add(5) # 增加集合的元素 set1: {0, 1, 2, 3, 4, 5}
set1.remove(5) # 去除集合中的指定元素 set1: {0, 1, 2, 3, 4}
set2=frozenset([1,2,3]) # 不可變集合,沒有add() remove()