如果图片加载不出来请到https://www.bilibili.com/read/cv243286,都是我写的
上一篇文章后面有大佬提给了两条建议,我们赶快来看看吧。
![](https://i-blog.csdnimg.cn/blog_migrate/f06edb60a55d86fc5dbb268688ce51b2.png)
str有很多内置函数,笔者没有介绍完。我们来看看这个join,括号里面是被分隔对象,前面是分隔符
![](https://i-blog.csdnimg.cn/blog_migrate/bce2cb8dd571952720f1d0aeb0f2179c.png)
用上面这种就很容易把列表转换为字符串了,元组,字符串,字典都可以用
![](https://i-blog.csdnimg.cn/blog_migrate/0f7e4b371ec454f9f2dc3f9df9827db7.png)
元组必须加小括号不然会报错,python会认为逗号是分隔了两个参数。这里再讲一下分片吧,a[::-1]第一个冒号是表示全部元素,第二个冒号加上数字表示步长:-1就是从右向左,用负步长需要注意第一个冒号前后的数字大小
![](https://i-blog.csdnimg.cn/blog_migrate/148f568eee65a09db9732562f15a49db.png)
![](https://i-blog.csdnimg.cn/blog_migrate/65399759d16ce6e9899d1ea10f21a250.png)
第一个冒号前没有填的是表示到边界,上图第一个冒号右边没有那就一直到左边界,也就是索引是0的元素(python索引开始值是可以自己设的,默认是0),并且包括这个元素。还需要注意第一个冒号后面的数是不包括进去的,对比一下上面两个图。如果是正步长
![](https://i-blog.csdnimg.cn/blog_migrate/6d3d4a39ce7cc03e5aaf2c41b2dae47e.png)
第一个冒号后面没有数字就一直到最大索引值的元素,也包含这个元素。
字典也是可以用join来连接,连接的是key,下面会说什么是字典和key
![](https://i-blog.csdnimg.cn/blog_migrate/a3ae4095d076e194101c5155cca3cd2d.png)
在这里再介绍一个bif内置函数split
![](https://i-blog.csdnimg.cn/blog_migrate/795d5b3ad8a9d170b1fa37221194de18.png)
可以看到split括号里是分隔的字符,这个内置函数返回的是一个列表,可以用join转为字符串。需要提醒的是,字符串的bif操作是不会改变原字符串的,它产生一个新的字符串,如果没有标签给这个新字符串,它很快会被python回收
![](https://i-blog.csdnimg.cn/blog_migrate/6497bb23c7879dc6cb5583c1bd3f5f8c.png)
上面操作都没与改变a
关于尾递归
![](https://i-blog.csdnimg.cn/blog_migrate/2baf6306cb77ff2448f3825600e87892.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8215c6e17d8d8ea074167c3c4095dcf2.png)
都摘自百度百科,这都是理论,下面我们举例感受,我们还是拿以前算阶乘为例
普通递归
![](https://i-blog.csdnimg.cn/blog_migrate/982f88d8f8cbd3e31da4451dbec92409.png)
我们来看他的内存占用情况:
a(5)
5*a(4)
5*4*a(3)
5*4*3*a(2)
5*4*3*2*a(1)
5*4*3*2*1
5*4*3*2
5*4*6
5*4
20
过程就是这样:要知道a(5)就得知道a(4),并且这个5还要存起来,要想知道a(4)就得知道a(3),并且5和4都要存起来,依此类推,最后直到返回条件a(1)=1,然后可以计算a(2)=2*a(1),再计算a(3)=3*a(2)...最后得到答案。
尾递归
![](https://i-blog.csdnimg.cn/blog_migrate/443dcce18d4185d4dbb3ed5e51607cdf.png)
尾递归需要两个参数,n我理解为还需要递归的次数,当n==0时,也就是不需要在递归时,返回结果,否则,继续递归,result是我们要的结果,一般会设置默认参数,这里是算阶乘所以默认是1,默认值视情况而定。我们来看内存占用
a(5,1)
a(4,5)
a(3,20)
a(2,60)
a(1,120)
120
迭代
![](https://i-blog.csdnimg.cn/blog_migrate/7b3927b5c239b7e287e9ebe5d6f9a677.png)
如何写一个尾递归?理论上只需要return后面是一个纯函数比如a(n-1,n*result),而不是n*a(n-1),后一种无法更新a函数里的实际参数,只是新建了一个栈,因为n和a(n-1)都需要存。尾递归和迭代内存占用都不多,但是函数调用压栈弹栈是需要时间的,所以我认为至少再计算阶乘这个问题上尾递归还是比迭代要慢。斐波那契数列我认为也不是一个尾递归,以求a(4)为例,内存占用:
a(4)
a(3)+a(2)
a(2)+a(1)+1
1+1+1
2+1
3
斐波那契和汉诺塔笔者想不出来怎么写尾递归,如果有高人,请在评论区指教,尾递归笔者参考了https://www.zhihu.com/question/20761771,有兴趣的可以去看下,笔者基本都说到了。笔者还要说一下,关于数据存储结构的问题,笔者还没有开始学习,解答不了,以后有机会可能学了数据结构还会来看以前发过的文章,在下面加评论。
这一讲开始我们学习字典,字典是一种映射类型,字典不是一种序列,字典的关键字我们叫做key,值叫做value,字典也可以叫做哈希表或者关系数组。比如你去查one的意思,one就是key,1就是value。字典用大括号括起来,字典调用要输入key而不是索引,它不是序列没有索引,我们来实践一下
![](https://i-blog.csdnimg.cn/blog_migrate/fb9d9213d729f35489860f86c9a9d515.png)
in函数只能访问key(如果不用bif的话),key不能是一个列表。元组和字符串都可以当一个key
![](https://i-blog.csdnimg.cn/blog_migrate/a52a9b46a54930a6384db6a4651da1d3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/38ff3b5a56329faf55f04f95d40d215b.png)
字典也不可以是一个key。
![](https://i-blog.csdnimg.cn/blog_migrate/44e309c04d407165bbc478b03a4d6602.png)
字典就是一种对应关系那么其实下面通过索引映射也是可行的,但是麻烦
![](https://i-blog.csdnimg.cn/blog_migrate/97615be134f85816a9e218f37fd7b7f2.png)
但是效率不高,也多少有些别扭。我们也可以用zip打包它们或者用前面学过的map()
![](https://i-blog.csdnimg.cn/blog_migrate/941381694a6d07c9efa042c6c86a7541.png)
创建字典还有以下方法
![](https://i-blog.csdnimg.cn/blog_migrate/de71276d25197e195defa5b1e90b90ab.png)
我们可以看到对应关系可以用元组,也可以用列表,也就是里面第一层括号,逗号前面是key后面是value,所有对应关系可以放在一个列表或者元组中,也就是从里向外第二层括号,因为dict只能有一个参数,第三层括号是dict这个工厂函数的,int,str,float,list,tuple都是工厂函数,它们产生特定类型。
还可以使用关键字,但是关键字只能是字符串的内容,比如
![](https://i-blog.csdnimg.cn/blog_migrate/1073c94dbfefc258fe3b2ff896353351.png)
但是关键字这种做法key不可以是元组,只能先把元组转化为字符串再提取内容,
![](https://i-blog.csdnimg.cn/blog_migrate/5968045eafe05bbcf0591d780299bbfb.png)
那么可不可以有key对应多个value呢?
![](https://i-blog.csdnimg.cn/blog_migrate/f773516abb3daa21baf2c5c8b94d2faa.png)
python报错了,是不可以的。
字典和列表不同的是,如果你给一个字典里不存在的key赋值,它不会报错,会加上这个key进去,但是相同的是,如果你直接访问一个不存在的key,它会报错
![](https://i-blog.csdnimg.cn/blog_migrate/76e412c66674d7ca146b3b7e45406b78.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1b4f78c36579404ad875ccd074ed3143.png)
这里还要说的是,大括号也不一定是字典,以前我们就见过大括号一次
![](https://i-blog.csdnimg.cn/blog_migrate/3543ad82b8056c99337574311ff34aaf.png)
a没有映射关系,只有key,我们看到他的类型是集合。
下面介绍一些dict的内置方法,你可以通过help(dict)来查看
第一个fromkeys
![](https://i-blog.csdnimg.cn/blog_migrate/2f1d46d27458a2fbb7dc2c84ed9bd8ee.png)
返回的是一个新的字典,有两个参数,第一个参数是key,第二个是value,第二个可以没有,默认是None。
![](https://i-blog.csdnimg.cn/blog_migrate/f36ad10d4147675cefdddad5c6a23a51.png)
注意只能有两个参数
![](https://i-blog.csdnimg.cn/blog_migrate/24397561d6d5d08fee31c23e07efcaca.png)
而且注意它生成的是新的字典,不会影响原来的字典,所以修改字典中的key对应的value是不能用它的
![](https://i-blog.csdnimg.cn/blog_migrate/484a2b9b2ea354b813848df34a285271.png)
下面是keys,values和items
![](https://i-blog.csdnimg.cn/blog_migrate/ccf4556156fab6c0de423ed0af917620.png)
![](https://i-blog.csdnimg.cn/blog_migrate/564741d69ef9ad00d58ca17a24ff7b8a.png)
举几个例子
![](https://i-blog.csdnimg.cn/blog_migrate/f946750066f117f17f9572725bf2e2ea.png)
get也是一种访问字典的方法
![](https://i-blog.csdnimg.cn/blog_migrate/3bac34ed9654b8fd08c251795b293f36.png)
![](https://i-blog.csdnimg.cn/blog_migrate/55c07fc28950ffdbcf1000d039a805d5.png)
可以看到和普通的访问不同,如果这个key在字典里不存在,get不会报错,默认会返回None,当然返回内容可以自己设置。如果单纯只是想知道这个key在不在字典里,可以直接用in和not in
![](https://i-blog.csdnimg.cn/blog_migrate/142b291259eaddfa2e8078c368f1a60f.png)
下面介绍和列表一样的clear
![](https://i-blog.csdnimg.cn/blog_migrate/173366e5efd2e8447cd3c0479c0210d0.png)
这里的道理笔者再列表那里就讲过了,python里的变量就是个标签。上图中的a.clear用了bif改变的是a这个标签对应的字典的内容,而a={}只是把a这个标签从原来的字典上撕下来,贴到空字典上而已。
今天由于笔者有事就只能先写到这里了,先给大家说声抱歉,笔者外公过世了。
![](https://i-blog.csdnimg.cn/blog_migrate/629c0a2199aca4e2c7eb120f8b4859a2.jpeg)
笔者再给出这个系列第二三讲的链接。
第二讲:http://blog.csdn.net/qq_41740705/article/details/79340828
第三讲:http://blog.csdn.net/qq_41740705/article/details/79342158
这两讲up不准备搬了,请自行查看
上一篇文章后面有大佬提给了两条建议,我们赶快来看看吧。
![](https://i-blog.csdnimg.cn/blog_migrate/f06edb60a55d86fc5dbb268688ce51b2.png)
str有很多内置函数,笔者没有介绍完。我们来看看这个join,括号里面是被分隔对象,前面是分隔符
![](https://i-blog.csdnimg.cn/blog_migrate/bce2cb8dd571952720f1d0aeb0f2179c.png)
用上面这种就很容易把列表转换为字符串了,元组,字符串,字典都可以用
![](https://i-blog.csdnimg.cn/blog_migrate/0f7e4b371ec454f9f2dc3f9df9827db7.png)
元组必须加小括号不然会报错,python会认为逗号是分隔了两个参数。这里再讲一下分片吧,a[::-1]第一个冒号是表示全部元素,第二个冒号加上数字表示步长:-1就是从右向左,用负步长需要注意第一个冒号前后的数字大小
![](https://i-blog.csdnimg.cn/blog_migrate/148f568eee65a09db9732562f15a49db.png)
![](https://i-blog.csdnimg.cn/blog_migrate/65399759d16ce6e9899d1ea10f21a250.png)
第一个冒号前没有填的是表示到边界,上图第一个冒号右边没有那就一直到左边界,也就是索引是0的元素(python索引开始值是可以自己设的,默认是0),并且包括这个元素。还需要注意第一个冒号后面的数是不包括进去的,对比一下上面两个图。如果是正步长
![](https://i-blog.csdnimg.cn/blog_migrate/6d3d4a39ce7cc03e5aaf2c41b2dae47e.png)
第一个冒号后面没有数字就一直到最大索引值的元素,也包含这个元素。
字典也是可以用join来连接,连接的是key,下面会说什么是字典和key
![](https://i-blog.csdnimg.cn/blog_migrate/a3ae4095d076e194101c5155cca3cd2d.png)
在这里再介绍一个bif内置函数split
![](https://i-blog.csdnimg.cn/blog_migrate/795d5b3ad8a9d170b1fa37221194de18.png)
可以看到split括号里是分隔的字符,这个内置函数返回的是一个列表,可以用join转为字符串。需要提醒的是,字符串的bif操作是不会改变原字符串的,它产生一个新的字符串,如果没有标签给这个新字符串,它很快会被python回收
![](https://i-blog.csdnimg.cn/blog_migrate/6497bb23c7879dc6cb5583c1bd3f5f8c.png)
上面操作都没与改变a
关于尾递归
![](https://i-blog.csdnimg.cn/blog_migrate/2baf6306cb77ff2448f3825600e87892.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8215c6e17d8d8ea074167c3c4095dcf2.png)
都摘自百度百科,这都是理论,下面我们举例感受,我们还是拿以前算阶乘为例
普通递归
![](https://i-blog.csdnimg.cn/blog_migrate/982f88d8f8cbd3e31da4451dbec92409.png)
我们来看他的内存占用情况:
a(5)
5*a(4)
5*4*a(3)
5*4*3*a(2)
5*4*3*2*a(1)
5*4*3*2*1
5*4*3*2
5*4*6
5*4
20
过程就是这样:要知道a(5)就得知道a(4),并且这个5还要存起来,要想知道a(4)就得知道a(3),并且5和4都要存起来,依此类推,最后直到返回条件a(1)=1,然后可以计算a(2)=2*a(1),再计算a(3)=3*a(2)...最后得到答案。
尾递归
![](https://i-blog.csdnimg.cn/blog_migrate/443dcce18d4185d4dbb3ed5e51607cdf.png)
尾递归需要两个参数,n我理解为还需要递归的次数,当n==0时,也就是不需要在递归时,返回结果,否则,继续递归,result是我们要的结果,一般会设置默认参数,这里是算阶乘所以默认是1,默认值视情况而定。我们来看内存占用
a(5,1)
a(4,5)
a(3,20)
a(2,60)
a(1,120)
120
迭代
![](https://i-blog.csdnimg.cn/blog_migrate/7b3927b5c239b7e287e9ebe5d6f9a677.png)
如何写一个尾递归?理论上只需要return后面是一个纯函数比如a(n-1,n*result),而不是n*a(n-1),后一种无法更新a函数里的实际参数,只是新建了一个栈,因为n和a(n-1)都需要存。尾递归和迭代内存占用都不多,但是函数调用压栈弹栈是需要时间的,所以我认为至少再计算阶乘这个问题上尾递归还是比迭代要慢。斐波那契数列我认为也不是一个尾递归,以求a(4)为例,内存占用:
a(4)
a(3)+a(2)
a(2)+a(1)+1
1+1+1
2+1
3
斐波那契和汉诺塔笔者想不出来怎么写尾递归,如果有高人,请在评论区指教,尾递归笔者参考了https://www.zhihu.com/question/20761771,有兴趣的可以去看下,笔者基本都说到了。笔者还要说一下,关于数据存储结构的问题,笔者还没有开始学习,解答不了,以后有机会可能学了数据结构还会来看以前发过的文章,在下面加评论。
![](https://i-blog.csdnimg.cn/blog_migrate/0195afc1bb7cc912d00d45e30be47f88.jpeg)
这一讲开始我们学习字典,字典是一种映射类型,字典不是一种序列,字典的关键字我们叫做key,值叫做value,字典也可以叫做哈希表或者关系数组。比如你去查one的意思,one就是key,1就是value。字典用大括号括起来,字典调用要输入key而不是索引,它不是序列没有索引,我们来实践一下
![](https://i-blog.csdnimg.cn/blog_migrate/fb9d9213d729f35489860f86c9a9d515.png)
in函数只能访问key(如果不用bif的话),key不能是一个列表。元组和字符串都可以当一个key
![](https://i-blog.csdnimg.cn/blog_migrate/a52a9b46a54930a6384db6a4651da1d3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/38ff3b5a56329faf55f04f95d40d215b.png)
字典也不可以是一个key。
![](https://i-blog.csdnimg.cn/blog_migrate/44e309c04d407165bbc478b03a4d6602.png)
字典就是一种对应关系那么其实下面通过索引映射也是可行的,但是麻烦
![](https://i-blog.csdnimg.cn/blog_migrate/97615be134f85816a9e218f37fd7b7f2.png)
但是效率不高,也多少有些别扭。我们也可以用zip打包它们或者用前面学过的map()
![](https://i-blog.csdnimg.cn/blog_migrate/941381694a6d07c9efa042c6c86a7541.png)
创建字典还有以下方法
![](https://i-blog.csdnimg.cn/blog_migrate/de71276d25197e195defa5b1e90b90ab.png)
我们可以看到对应关系可以用元组,也可以用列表,也就是里面第一层括号,逗号前面是key后面是value,所有对应关系可以放在一个列表或者元组中,也就是从里向外第二层括号,因为dict只能有一个参数,第三层括号是dict这个工厂函数的,int,str,float,list,tuple都是工厂函数,它们产生特定类型。
还可以使用关键字,但是关键字只能是字符串的内容,比如
![](https://i-blog.csdnimg.cn/blog_migrate/1073c94dbfefc258fe3b2ff896353351.png)
但是关键字这种做法key不可以是元组,只能先把元组转化为字符串再提取内容,
![](https://i-blog.csdnimg.cn/blog_migrate/5968045eafe05bbcf0591d780299bbfb.png)
那么可不可以有key对应多个value呢?
![](https://i-blog.csdnimg.cn/blog_migrate/f773516abb3daa21baf2c5c8b94d2faa.png)
python报错了,是不可以的。
字典和列表不同的是,如果你给一个字典里不存在的key赋值,它不会报错,会加上这个key进去,但是相同的是,如果你直接访问一个不存在的key,它会报错
![](https://i-blog.csdnimg.cn/blog_migrate/76e412c66674d7ca146b3b7e45406b78.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1b4f78c36579404ad875ccd074ed3143.png)
这里还要说的是,大括号也不一定是字典,以前我们就见过大括号一次
![](https://i-blog.csdnimg.cn/blog_migrate/3543ad82b8056c99337574311ff34aaf.png)
a没有映射关系,只有key,我们看到他的类型是集合。
下面介绍一些dict的内置方法,你可以通过help(dict)来查看
第一个fromkeys
![](https://i-blog.csdnimg.cn/blog_migrate/2f1d46d27458a2fbb7dc2c84ed9bd8ee.png)
返回的是一个新的字典,有两个参数,第一个参数是key,第二个是value,第二个可以没有,默认是None。
![](https://i-blog.csdnimg.cn/blog_migrate/f36ad10d4147675cefdddad5c6a23a51.png)
注意只能有两个参数
![](https://i-blog.csdnimg.cn/blog_migrate/24397561d6d5d08fee31c23e07efcaca.png)
而且注意它生成的是新的字典,不会影响原来的字典,所以修改字典中的key对应的value是不能用它的
![](https://i-blog.csdnimg.cn/blog_migrate/484a2b9b2ea354b813848df34a285271.png)
下面是keys,values和items
![](https://i-blog.csdnimg.cn/blog_migrate/ccf4556156fab6c0de423ed0af917620.png)
![](https://i-blog.csdnimg.cn/blog_migrate/564741d69ef9ad00d58ca17a24ff7b8a.png)
举几个例子
![](https://i-blog.csdnimg.cn/blog_migrate/f946750066f117f17f9572725bf2e2ea.png)
get也是一种访问字典的方法
![](https://i-blog.csdnimg.cn/blog_migrate/3bac34ed9654b8fd08c251795b293f36.png)
![](https://i-blog.csdnimg.cn/blog_migrate/55c07fc28950ffdbcf1000d039a805d5.png)
可以看到和普通的访问不同,如果这个key在字典里不存在,get不会报错,默认会返回None,当然返回内容可以自己设置。如果单纯只是想知道这个key在不在字典里,可以直接用in和not in
![](https://i-blog.csdnimg.cn/blog_migrate/142b291259eaddfa2e8078c368f1a60f.png)
下面介绍和列表一样的clear
![](https://i-blog.csdnimg.cn/blog_migrate/173366e5efd2e8447cd3c0479c0210d0.png)
这里的道理笔者再列表那里就讲过了,python里的变量就是个标签。上图中的a.clear用了bif改变的是a这个标签对应的字典的内容,而a={}只是把a这个标签从原来的字典上撕下来,贴到空字典上而已。
今天由于笔者有事就只能先写到这里了,先给大家说声抱歉,笔者外公过世了。笔者看到辛苦写的文章只有这么少的喜欢收藏和评论,内心更加悲痛,说不定就拖更甚至不更了呢。所以求各位小伙伴觉得好的话随手点个喜欢或者收藏,谢谢大家。
![](https://i-blog.csdnimg.cn/blog_migrate/7228eb62dd65cf6542223ed96bd45ebb.jpeg)