零基础入门学习Python P24-27 递归-斐波那契数列及汉诺塔、字典

180 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

P24 递归 - 斐波那契数列

def fbnq(x):
    if x ==1 or x == 2:
        return 1
    return fbnq(x-1) + fbnq(x-2)

fbnq(3)

image.png

当n>35,递归所需时间就越深 递归与迭代: 当递归层数越深时,所需要的时间和空间越大,层数深的情况下建议用迭代。

课后作业

  1. 使用递归编写一个十进制转换为二进制的函数(要求采用“取2取余”的方式,结果与调用bin()一样返回字符串形式)。
def bina(x):
    if x<2:
        return str(x)
    return bina(x // 2 ) + str(x % 2)

bina(10)

image.png

  1. 写一个函数get_digits(n),将参数n分解出每个位的数字并按顺序存放到列表中。举例:get_digits(12345) ==> [1, 2, 3, 4, 5]
bina(10)
'1010'
def get_digits(n):
    if n<10:
        return [n]
    return get_digits(n // 10) + [n % 10]

get_digits(12345)
[1, 2, 3, 4, 5]

image.png

  1. 还记得求回文字符串那道题吗?现在让你使用递归的方式来求解,亲还能骄傲的说我可以吗?
def huiwen(s):
    if len(s) == 1 or s == '':
        return True
    if s[0] == s[len(s)-1]:
        return huiwen(s[1:len(s)-1])
    return False

image.png

  1. 使用递归编程求解以下问题:

有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?

def age(x):
    if x == 1:
        return 10
    else:
        return age(x-1) + 2

age(5)
18

image.png

P25 递归 - 汉诺塔

image.png 解题 a b c三根柱子,将n个盘子从a 挪到b(通过 c),递归分为3步: 1、将n-1个盘子从a 挪到 c(通过 b) 2、将第n个盘子从a 挪到 b 3、将c上面的n-1个盘子 从c 挪到 b(通过 a) 0、特殊:如果n=1,那么可以把n直接从a 挪到b

下面代码是挪用模型,需要输出的内容根据题面另外设置。

print('--------Fred-2022-7-28-----------')

def hnt(x,a,b,c):
    if x == 1:
        b.insert(0,a[0])
        del a[0]
    else:
        a,c,b = hnt(x-1,a,c,b)
        b.insert(0,a[0])
        del a[0]
        c,b,a = hnt(x-1,c,b,a)


    return a,b,c

n = int(input('输入汉诺塔层数:'))
a = [i for i in range(1,n+1)]
b = []
c = []

print(hnt(n,a,b,c))

P26 字典

类比生活中用的字典,Python字典的“词”称为key,字典中“含义”称为值(value) 字典是Python唯一的一种映射类型。映射一对一,一对多的关系。 序列中的索引与索引值毫无关系。例如: l = ['a','b',[1,2,3]] l[3] = [1,2,3]

字典的索引就是key,key可以是具体值,与索引值一一对应。 list、str是数据类型

字典的一个键值组合,成为项 键可以是字符串、int、float 值可以是任意数据类型 创造空字典:d = {} 创建字典: 键值创建:d = {a:b,c:d} d = dict(((a,b),(c,d))) d = dict([(a,b),(c,d)])

键赋值:如果键存在在字典里,则修改值;如果不存在,则自动创建键,并赋值。

课后作业

  1. 当你听到小伙伴们在谈论“映射”、“哈希”、“散列”或者“关系数组”的时候,事实上他们就是在讨论什么呢? 字典

  2. 尝试一下将数据('F': 70, 'C': 67, 'h': 104, 'i': 105, 's': 115)创建为一个字典并访问键 'C' 对应的值? dic = {'F': 70, 'C': 67, 'h': 104, 'i': 105, 's': 115} dic['C']

  3. 用方括号(“[]”)括起来的数据我们叫列表,那么使用大括号(“{}”)括起来的数据我们就叫字典,对吗? 不对,集合也是大括号括起来的:{a,b,c} 集合里面是单个的元素,不是键值

  4. 你如何理解有些东西字典做得到,但“万能的”列表却难以实现(臣妾做不到T_T)? 查询时间复杂度O(1)

  5. 下边这些代码,他们都在执行一样的操作吗?你看得出差别吗? a = dict(one=1, two=2, three=3) b = {'one': 1, 'two': 2, 'three': 3} c = dict(zip(['one', 'two', 'three'], [1, 2, 3])) d = dict([('two', 2), ('one', 1), ('three', 3)]) e = dict({'three': 3, 'one': 1, 'two': 2}) 都一样

字典的5种定义方法

  1. 如图,你可以推测出打了马赛克部分的代码吗?

image.png

动动手:

  1. 尝试利用字典的特性编写一个通讯录程序吧,功能如图:

image.png

dict{人名:{电话:str}}

P27 字典

dict.fromkeys(keys,value)

keys可以是包含多个元素的元组,一一生成键,value会被看成一个整体,为每个键赋值value。这个函数会重新创建一个字典,不会修改原dict的值。

image.png

dict.keys()

将字典中所有的key生成一个list

dict.values()

将字典中所有的值生成一个list

dict.items()

将字典中所有的项形成元组,生成一个list

image.png

字典访问:dict.get(key,默认值) 当key在字典中时,返回key值,否则返回默认值,不会报错 如果key不在字典中,用dict[key]直接访问的话,会报错KeyError

关系操作符

key in dict 查找索引 序列的关系操作符是查找值。

清空字典

dict.clear() = None 彻底清空数据 dict = {} = {} 数据没清空,如果有其他变量指向原dict数据,则那些变量还是可以访问原数据

dict.copy() 数据拷贝 dict.pop() 弹出一项 dict.setdefault(键,值) a.update(b) 用字典b中的键值更新字典a,如果b的键在a中存在,就修改a的键值,如果不存在,就新增一项。

课后作业

  1. Python的字典是否支持一键(Key)多值(Value)? 支持

  2. 在字典中,如果试图为一个不存在的键(Key)赋值会怎样? 会创建key,并赋值

  3. 成员资格操作符(in和not in)可以检查一个元素是否存在序列中,当然也可以用来检查一个键(Key)是否存在字典中,那么请问哪种的检查效率更高些?为什么? 字典效率更高,因为是hash码索引,时间复杂度O1 序列时间复杂度On

  4. Python对键(Key)和值(Value)有没有类型限制? key:str、int、float value没有

  5. 请目测下边代码执行后,字典dict1的内容是什么? dict1.fromkeys((1, 2, 3), ('one', 'two', 'three')) dict1.fromkeys((1, 3), '数字') 1:'数字' 2:('one', 'two', 'three') 3:'数字'

  6. 如果你需要将字典dict1 = {1: 'one', 2: 'two', 3: 'three'}拷贝到dict2,你应该怎么做? dict2 = dict1.copy()

编程作业

  1. 尝试编写一个用户登录程序(这次尝试将功能封装成函数),程序实现如图:

image.png

dict={用户名:密码}