Python 之 遞歸 字典 集合

馬山要期末考試了,又要開始卑微的學習了

遞歸的使用

  • 遞歸函數的書寫,踩坑: 函數語句中都會有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所示,有三根柱子,若干個大小不等的圓盤按順序依次疊落在起點(左側)的柱子上,通過多次移動後,全部圓盤要疊落在終點(右側)的柱子上。移動必需遵守兩個原則:

  1. 每次只能移動一個圓盤
  2. 移動過程中,大圓盤不允許覆蓋在小圓盤上。
    漢諾塔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() 可以根據鍵來獲取 值,也可以根據鍵對來獲取 值,如果字典中不存在該鍵值對,則自動增加並返回 值
  • innot 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()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章