python递归函数的特点_python学习-递归函数-高级特性-切片-迭代-列表的生成

1. 递归函数

在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:

fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。

于是,fact(n)用递归的方式写出来就是:

def fact(n):

if n==1:

return 1

return n * fact(n - 1)

上面就是一个递归函数。可以试试:

>>> fact(1)

1

>>> fact(5)

120

>>> fact(100)

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

如果我们计算fact(5),可以根据函数定义看到计算过程如下:

===> fact(5)

===> 5 * fact(4)

===> 5 * (4 * fact(3))

===> 5 * (4 * (3 * fact(2)))

===> 5 * (4 * (3 * (2 * fact(1))))

===> 5 * (4 * (3 * (2 * 1)))

===> 5 * (4 * (3 * 2))

===> 5 * (4 * 6)

===> 5 * 24

===> 120

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

汉诺塔方法用递归实现:

# 其实是不断变换 a,b,c 的位置

def move(n, a, b, c):

if n > 1:

move(n-1, a, c, b)

move(1, a, b, c)

move(n-1, b, a, c)

elif n == 1:

print(a + ' --> ' + c)

move(3, 'A', 'B', 'C')

2.高级特性

在Python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。

基于这一思想,我们来介绍Python中非常有用的高级特性,1行代码能实现的功能,决不写5行代码。请始终牢记,代码越少,开发效率越高。

2.1 切片

取一个list或tuple的部分元素是非常常见的操作。

>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']

对这种经常取指定索引范围的操作,用循环十分繁琐,因此,Python提供了切片(Slice)操作符,能大大简化这种操作。

对应上面的问题,取前3个元素,用一行代码就可以完成切片:

>>> L[0:3]

['Michael', 'Sarah', 'Tracy']

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。

如果第一个索引是0,还可以省略:

>>> L[:3]

['Michael', 'Sarah', 'Tracy']

也可以从索引1开始,取出2个元素出来:

>>> L[1:3]

['Sarah', 'Tracy']

类似的,既然Python支持L[-1]取倒数第一个元素,那么它同样支持倒数切片,试试:

>>> L[-2:]

['Bob', 'Jack']

>>> L[-2:-1]

['Bob']

记住倒数第一个元素的索引是-1。

切片操作十分有用。我们先创建一个0-99的数列:

前10个数,每两个取一个:

>>> L[:10:2]

[0, 2, 4, 6, 8]

所有数,每5个取一个:

>>> L[::5]

[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

甚至什么都不写,只写[:]就可以原样复制一个list:

>>> L[:]

[0, 1, 2, 3, ..., 99]

tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:

>>> (0, 1, 2, 3, 4, 5)[:3]

(0, 1, 2)

字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:

>>> 'ABCDEFG'[:3]

'ABC'

>>> 'ABCDEFG'[::2]

'ACEG'

2.2 迭代

如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。

list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代:

>>> d = {'a': 1, 'b': 2, 'c': 3}

>>> for key in d:

... print(key)

...

a

c

b

因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。

由于字符串也是可迭代对象,因此,也可以作用于for循环:

>>> for ch in 'ABC':

... print(ch)

...

A

B

C

所以,当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。

那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:

>>> from collections import Iterable

>>> isinstance('abc', Iterable) # str是否可迭代

True

>>> isinstance([1,2,3], Iterable) # list是否可迭代

True

>>> isinstance(123, Iterable) # 整数是否可迭代

False

最后一个小问题,如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

>>> for i, value in enumerate(['A', 'B', 'C']):

... print(i, value)

...

0 A

1 B

2 C

最后一个小问题,如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

>>> for i, value in enumerate(['A', 'B', 'C']):

... print(i, value)

...

0 A

1 B

2 C

上面的for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:

>>> for x, y in [(1, 1), (2, 4), (3, 9)]:

... print(x, y)

...

1 1

2 4

3 9

任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环

2.3 列表的生成

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):

>>> list(range(1, 11))

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

列表生成式则可以用一行语句代替循环生成上面的list:

>>> [x * x for x in range(1, 11)]

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

>>> [x * x for x in range(1, 11) if x % 2 == 0]

[4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']

['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }

>>> for k, v in d.items():

... print(k, '=', v)

...

y = B

x = A

z = C

因此,列表生成式也可以使用两个变量来生成list:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }

>>> [k + '=' + v for k, v in d.items()]

['y=B', 'x=A', 'z=C']

最后把一个list中所有的字符串变成小写:

>>> L = ['Hello', 'World', 'IBM', 'Apple']

>>> [s.lower() for s in L]

['hello', 'world', 'ibm', 'apple']

作业:修改列表生成式,让列表显示只显示字符串且全部为小写字母

L1 = ['Hello', 'World', 18, 'Apple', None]

L2 = [ A.lower() for A in L1 if isinstance(A, str)]

#print(L2)

fu

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
廖雪峰的 Python 教程 4 关于作者 4 Python 简介 6 安装 Python 9 Python 解释器 12 第一个 Python 程序 14 使用文本编辑器 17 Python 代码运行助手 20 输入和输出 25 Python 基础 28 数据类型和变量 29 字符串和编码 37 使用 list 和 tuple 46 条件判断 53 循环 58 使用 dict 和 set 63 函数 70 调用函数 72 定义函数 75 函数的参数 80 函数 93 高级特性 97 切片 98 代 102 列表生成式 105 生成器 109 代器 118 函数式编程 121 高阶函数 122 map/reduce 125 filter 130 sorted 134 返回函数 137 匿名函数 141 装饰器 143 偏函数 148 模块 151 使用模块 153 安装第三方模块 157 面向对象编程 159 类和实例 161 访问限制 165 继承和多态 169 获取对象信息 175 实例属性和类属性 183 面向对象高级编程 185 使用 slots 186 使用@property 189 多重继承 193 定制类 198 使用枚举类 209 使用元类 212 错误、调试和测试 221 错误处理 222 调试 233 单元测试 239 文档测试 244 IO 编程 249 文件读写 250 StringIO 和 BytesIO 254 操作文件和目录 257 序列化 261 进程和线程 267 多进程 269 多线程 278 ThreadLocal 285 进程 vs. 线程 289 分布式进程 292 正则表达式 298 常用内建模块 304 datetime 305 collections 312 base64 317 struct 320 hashlib 322 itertools 327 contextlib 331 XML 336 HTMLParser 341 urllib 344 常用第三方模块 349 virtualenv 355 图形界面 357 网络编程 361 TCP/IP 简介 362 TCP 编程 364 UDP 编程 370 电子邮件 373 SMTP 发送邮件 375 POP3 收取邮件 384 访问数据库 390 使用 SQLite 395 使用 MySQL 399 使用 SQLAlchemy 403 Web 开发 408 HTTP 协议简介 410 HTML 简介 417 WSGI 接口 422 使用 Web 框架 428 使用模板 433 异步 IO 439 协程 441 asyncio 445 async/await 449 aiohttp 451 实战 453 Day 1 - 搭建开发环境 457 Day 2 - 编写 Web App 骨架 459 Day 3 - 编写 ORM 461 Day 4 - 编写 Model 471 Day 5 - 编写 Web 框架 477 Day 6 - 编写配置文件 484 Day 7 - 编写 MVC 486 Day 8 - 构建前端 488 Day 9 - 编写 API 499 Day 10 - 用户注册和登录 501 Day 11 - 编写日志创建页 511 Day 12 - 编写日志列表页 520 Day 13 - 提升开发效率 527 Day 14 - 完成 Web App 532 Day 15 - 部署 Web App 534 Day 16 - 编写移动 App 544 FAQ 546 期末总结 549
Python教程 ................................................................................................................... 5 Python简介 ................................................................................................................... 7 安装Python ................................................................................................................. 12 Python解释器 ............................................................................................................. 16 第一个Python程序 .................................................................................................... 18 使用文本编辑器 ......................................................................................................... 19 Python代码运行助手 ................................................................................................. 25 输入和输出 ................................................................................................................. 28 Python基础 ................................................................................................................. 32 数据类型和变量 ......................................................................................................... 33 字符串和编码 ............................................................................................................. 43 使用list和tuple ......................................................................................................... 53 条件判断 ..................................................................................................................... 60 循环 ............................................................................................................................. 64 使用dict和set ............................................................................................................ 67 函数 ............................................................................................................................. 74 调用函数 ..................................................................................................................... 76 定义函数 ..................................................................................................................... 78 函数的参数 ................................................................................................................. 83 函数 ..................................................................................................................... 97 高级特性 ................................................................................................................... 101 切片 ........................................................................................................................... 102 代 ........................................................................................................................... 105 列表生成式 ............................................................................................................... 108 生成器 ....................................................................................................................... 111 代器 ....................................................................................................................... 119 函数式编程 ............................................................................................................... 122 高阶函数 ................................................................................................................... 123 map/reduce ................................................................................................................ 126 filter............................................................................................................................ 131 sorted.......................................................................................................................... 135 Python3 基础教程【完整版】 http://www.yeayee.com/ 2/531 返回函数 ................................................................................................................... 138 匿名函数 ................................................................................................................... 141 装饰器 ....................................................................................................................... 143 偏函数 ....................................................................................................................... 147 模块 ........................................................................................................................... 150 使用模块 ................................................................................................................... 153 安装第三方模块 ....................................................................................................... 157 面向对象编程 ........................................................................................................... 160 类和实例 ................................................................................................................... 162 访问限制 ................................................................................................................... 167 继承和多态 ............................................................................................................... 170 获取对象信息 ........................................................................................................... 177 实例属性和类属性 ................................................................................................... 184 面向对象高级编程 ................................................................................................... 185 使用__slots__ ............................................................................................................ 185 使用@property .......................................................................................................... 188 多重继承 ................................................................................................................... 191 定制类 ....................................................................................................................... 196 使用枚举类 ............................................................................................................... 207 使用元类 ................................................................................................................... 209 错误、调试和测试 ................................................................................................... 218 错误处理 ................................................................................................................... 219 调试 ........................................................................................................................... 229 单元测试 ................................................................................................................... 235 文档测试 ................................................................................................................... 240 IO编程 ...................................................................................................................... 245 文件读写 ................................................................................................................... 247 StringIO和BytesIO ................................................................................................. 251 操作文件和目录 ....................................................................................................... 253 序列化 ....................................................................................................................... 257 进程和线程 ............................................................................................................... 263 多进程 ....................................................................................................................... 26

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值