6. 高阶函数

更新 發佈閱讀 22 分鐘

Hi,大家好。 我是茶桁。

本节课,我们来学习一下Python中的「高阶函数」。

递归函数

让我们先来了解一下,什么是递归函数。

递归函数就是定义一个函数,然后在此函数内,自己调用自己。

既然是自己调用自己,那这个函数必须要有一个结束才行,否则会一直重复的调用下去,直到调用层数越来越多,最终会导致栈溢出。

让我们先写一个雏形:

 # 初步认识一下递归函数
 def recursion(num):
     print(num)
     recursion(num - 1)
 ​
 recursion(3)
 ​
 # 执行结果
 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 ....
 ​
 RecursionError: maximum recursion depth exceeded while calling a Python object

最后,导致栈溢出,程序报错。

那么这个程序到底做了什么?

首先,我们定义了一个函数,然后执行,执行的时候给了一个参数3

进入程序之后,先将3打印了一遍,然后在函数内部,又调用了一遍自己,参数为3-1,也就是传了一个参数2,在进入函数之后,打了了2, 继续自己调用自己,传参2-11-1, 0-1, ...就这样一直循环下去。

那么我们怎么样让这个程序停下来?就是在函数自己调用自己之前,加上一个限制条件:

 # 初步认识一下递归函数 3 2 1 0
 def recursion(num):
     print(num)
     # 检测当前值是否到0
     if num > 0:
         # 调用函数本身
         recursion(num - 1)
 recursion(3)
 ​
 # 执行结果
 3
 2
 1
 0

我们给调用之前加了一个条件,如果num > 0才允许继续执行,这样,当程序传递了1-1之后,执行了最后一次打印,然后就不向下执行了。

不过不要以为程序到这里就结束了,我们多加一行代码试试看:

 # 初步认识一下递归函数 3 2 1 0
 def recursion(num):
     print(num, end=" ")
     # 检测当前值是否到0
     if num > 0:
         # 调用函数本身
         recursion(num - 1)
     print(num, end=" ") # 又加了一个print函数
 recursion(3)
 ​
 # 执行结果
 3 2 1 0 0 1 2 3

如果你不知道程序做了什么,我们稍微分析一下:

 解析当前递归函数的执行过程:
 ```  recursion(3) ==> 3      recursion(3-1) ==> 2          recursion(2-1) ==> 1              recursion(1-1) ==> 0              recursion(0) ==> 0          recursion(1) ==> 1      recursion(2) ==>2  recursion(3) ==> 3  ```

也就是,在递归函数中,程序是一层一层的进入,然后再一层一层的返回。

这就好像是, 我们在上学的时候,你坐在最后一排,但是你有个心仪的女孩坐在最前面。你想要对方电话,这个时候你传递一个纸条给前面的同学,前面的同学再往前传,一直往前传到女孩手里。女孩看完之后,写完回复再一次次的传回来。最后你满怀期待的打开一看:“滚。”

当然,我们的递归函数和这个不同的地方是最后不会多加那个“滚”字。

回调函数

什么是回调函数呢?

我们首先来思考一个问题:

 def func(a):
     print(a)
 ​
 func(a)

在这个简单的函数中,我们已经学会了传值a给到func(),那么参数到底可以传一些什么进去?a可以是什么?能不能是一个函数呢?

这就引出了我们现在的内容:

 # 带有回调函数参数的函数
 def func(obj):
     print(obj, type(obj))
     # 并且在函数中调用传递进来的形参函数
     obj()
 ​
 def _self():
     print("i am _self")
 ​
 func(_self)
 ​
 # 执行结果
 <function _self at 0x111ed4280> <class 'function'>
 i am _self

可以看到,我们选择执行的是func函数,但是最后打印出了_self函数中语句。原因就是我们在执行func函数的时候,将_self函数作为参数传递给了func的形参obj, 我们在其中打印了obj以及obj的类型,并且最后执行了一下obj, 实际上也就是执行了一遍_self函数。

如果在一个函数中要求传递的参数是一个函数作为参数,并且在函数中使用了传递进来的函数,那么这个函数我们就可以称为是一个回调函数

我们拿系统内部的一个现成的函数来重新封装一个新的函数来试试:

 # 做一个数学计算的函数
 def func(x, y, obj):
     """
    此函数用来整合其他的数学运算
    在当前函数中,需要接收三个参数,前两个为数值,最后一个为函数
    x, y: int
    f: function
    :return:
    """
     print(obj(x, y))
 ​
 func(2, 3, pow)
 ​
 # 执行结果
 8


在日后使用这个函数的时候,就可以传入数值和要做什么计算的方法,就可以了。

当然,这个函数写的并不完善,比如,我们在执行func(2, 3, sum)的时候就会报错,原因是因为sum()函数内部是要进行迭代的的,然而int类型中没有魔法方法__iter__, 所以无法迭代。所以,要想这个函数具有通用性,还需要在内部完成很多工作。

闭包函数

之前我们在回调函数中将函数作为参数进行了传递,那么问题来了,既然函数能作为参数进行传递,那能不能作为参数被return呢?

 def person():
     money = 0
     def work():
         print(money)
     return work
 ​
 person()
 ​
 # 执行结果
 <function __main__.person.<locals>.work()>

我们可以看到,work函数被成功返回出来了。但是并未继续执行, 因为其内部的print()没起作用。

我们用一个变量来接收这个返回的函数:

 def person():
     money = 0
     def work():
         print(money)
     return work
 ​
 res = person()
 res()
 ​
 # 执行结果
 0

说明res接收到返回的work()函数,并且最后执行成功了。

好了,让我们继续为这个函数做一点什么,看看有什么变化。

 def person():
     money = 0
     def work():
         nonlocal money
         money += 100
         print(money)
     return work
 ​
 res = person()
 res()
 ​
 # 执行结果
 100

这个结合前几节所讲的内容就很好理解了对吧? nonlocal关键字拿到上一层函数定义的变量,然后在内层函数中进行使用,最后打印出来。

那我们继续执行会如何?让我们多执行几次:

 # 定义一个函数
 def person():
     money = 0  # 函数中定义了一个局部变量
     # 定义内函数
     def work():
         nonlocal money   # 在内函数中使用了外函数的临时变量
         money += 100
         print(money)
     # 在外函数中返回了内函数,这个内函数就是闭包函数
     return work
 ​
 res = person() # return work res = work
 res() # res() == work()
 res()
 res()
 res()
 res()
 # 此时 就不能够在全局中对money这个局部变量进行任何操作了,
 # 闭包的作用:保护了函数中的变量不受外部的影响,但是又能够不影响使用

你会不会认为会一直打印100? 让我们看看执行结果到底是怎样的:

 100
 200
 300
 400
 500

怎么样,是不是完全没想到?这个就是闭包函数的特点。

在一个函数内返回了一个内函数,并且这个返回的内函数还使用了外函数中局部变量,这个就是闭包函数。其特点为:

  • 在外函数中定义了局部变量,并且在内部函数中使用了这个局部变量
  • 在外函数中返回了内函数,返回的内函数就是闭包函数
  • ⚠️ 主要在于保护了外函数中的局部变量,既可以被使用,又不会被破坏。
  • 检测一个函数是否为闭包函数,可以使用func.__closure__,如果是闭包函数返回cell

匿名函数 -- lambda表达式

首先,我们先弄清楚什么是匿名函数: 匿名函数的意思就是说可以不使用def来定义,并且这个函数也没有名字。

在Python中,我们可以使用lambda表达式来定义匿名函数。我们需要注意,lambda仅仅是一个表达式,并不是一个代码块,所以lambda又称为一行代码的函数。

lambda表达式中,也有形参,并且不能够访问除了自己的形参之外的任何数据,包括全局变量。其语法如下:

 # 语法:
 lambda [参数列表]:返回值

让我们来尝试写写看,我们先来定义一个普通的加法运算的函数:

 # 封装一个函数做加法运算
 # 普通函数
 def sum(x, y):
     return x+y
 ​
 print(sum(2, 3))

毫无疑问,执行结果为5。那么接下来,用lambda该怎么写呢?

 # 改成lambda表达式来封装
 res = lambda x, y:x+y
 print(res(4, 4))
 ​
 # 执行结果
 8

结合闭包函数的讲解,这里就应该很容易看懂了吧?一样的地方就是,使用了一个变量res来接收这个返回的函数,然后执行res函数。

让我们再来一段:

 res = lambda sex:"很man" if sex=='male' else '很nice'
 print(res('female'))
 ​
 # 执行结果
 很nice

只看结果的话,我们很清楚这段函数最后执行到了else语句内。但是是如何进入的呢?让我们将这段代码用普通函数的写法展开来看看:

 def func(sex):
     if sex == 'male':
         return '很man'
     else:
         return '很nice'
 ​
 func('female')

这样是不是很清晰了?回过头来让我们看刚才那段lambda表达式,我们可以这样去看:

 #  lambda 参数列表: 真区间 if 表达式判断 else 假区间
 lambda sex: '很man' if sex=='male' else '很nice'
 ​
 # 然后用一个变量接收函数
 res = lambda sex: '很man' if sex=='male' else '很nice'

所以可以看出来,其实lambda十分的方便,并且并不难理解,当你习惯了lambda之后,会非常便捷。

迭代器

迭代器是一个很有意思的功能,可以说是Python中最具特色的功能之一,它是访问集合元素的一种方式。

迭代器是一个可以记住访问遍历的位置的对象。从集合的第一个元素开始访问,直到集合中的所有元素被访问完毕。

迭代器只能是从前往后一个一个的遍历,不能后退。

我们把之前一直使用的range()拿过来看:

 # range(10, 3, -1) 返回一个可迭代的对象
 for i in range(10, 3, -1):
     print(i, end=" ")
     
 # 执行结果
 10 9 8 7 6 5 4

表面上来看,似乎range()本身就是一个迭代器,可是我们来尝试做个实验:

 x = range(5)
 print(next(x))
 ​
 # 执行结果
 TypeError: 'range' object is not an iterator

当我们尝试调用next()函数的时候报错了,被告知range不是一个迭代器。

那么,range不是迭代器,究竟是什么呢?这里我们就要先深入研究下迭代器的特性:

严格来说,迭代器是指实现了迭代协议的对象,迭代协议是指实现了iter方法并返回一个实现了next方法的迭代器对象,并通过StopIterator一场标识迭代完成。

iter()

iter()能把迭代的对象,转为一个迭代器对象,其参数为可迭代的对象(str, list, tuple, dict), 返回值为迭代器对象。其中需要注意的一点是:迭代器一定是一个可以迭代的对象,但是可迭代的对象并不一定是迭代器。

我们在迭代器上使用iter会得到相同的对象:

 i = iter([1, 2, 3])
 print(iter(i) is i)
 print(id(iter(i)))
 print(id(i))
 ​
 # 执行结果
 True
 4425502096
 4425502096

基于此,我们可以这样实现:

 i = iter([1, 2, 3, 4])
 list(zip(i, i))
 ​
 # 执行结果
 [(1, 2), (3, 4)]

next()

next()函数可以去调用迭代器,并返回迭代器中的下一个数据。

我们使用iter函数可以从任何可迭代对象中获取一个迭代器:

 a = iter([1, 2, 3])
 print(a)
 print(next(a))
 print(1 in a)
 ​
 # 执行结果
 <list_iterator object at 0x124111a50>
 1
 False

可以看到,我们使用iter函数可以从任何可迭代对象中获取一个迭代器。而且迭代器有个特点,即每次用完一个元素即消耗掉该元素,不会保留在迭代器中,也就是说,是一次性的。

 res = iter([1, 2, 3, 4])
 print(next(res), end=" ")
 print(next(res), end=" ")
 print(next(res), end=" ")
 print(next(res), end=" ")
 # print(next(res))
 r = list(res)
 print(r)
 ​
 # 执行结果
 1 2 3 4 []

可以看到,list里面已经空了。

我们用for来取值:

 res = iter([1, 2, 3, 4])
 for i in res:
     print(i, end=" ")
 ​
 r = list(res)
 print(r)
 ​
 # 执行结果
 1 2 3 4 []

for直接将迭代内的元素全部取完了,所以最后打印下一个值的时候也显示空了。所以我们可以得到迭代器的取值方案:


迭代器的取值方案

  • next():调用一次获取一次,直到数据被取完。
  • list():使用list函数直接取出迭代器中的所有数据。
  • for:使用for循环遍历迭代器的数据


总结一下:

  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:iter()next()
  • 字符串,列表或元组对象都可用于创建迭代器:


那么,再回过头来看看range

range可以像任何其他可迭代对象一样循环使用,但是它并不具备迭代器中的一些特性,比如,我们之前实验过,range并不能使用next方法,而我们可以从range中得到一个迭代器:

 iter(range(3))
 ​
 # 执行结果
 <range_iterator at 0x124184570>

我们在迭代器中使用元素就会消耗掉该元素,但是我们遍历一个range对象并不消耗它, 比如:

raw-image

很明显我们可以重复使用。

来一个更直接的,我们之前用for获取了迭代里的值,我们对range()也来使用一下看看会不会有不同的结果:

 res = range(1,5)
 for i in res:
     print(i, end=" ")
 ​
 r = list(res)
 print(r)
 ​
 # 执行结果
 1 2 3 4 [1, 2, 3, 4]

一样的代码,对象不同。我们可以明显看到区别,range拿到最后里面的元素并没有减少。这也说明了,range并不是迭代器。

实际上,range的迭代是通过iter协议来实现的,只是一种类似迭代器的鸭子类型,并非真正的迭代器。

其实,有一种可以直接检测迭代器和可迭代对象的方法:

 # 检测迭代器和可迭代对象
 from collections.abc import Iterator, Iterable
 ​
 varstr = '123456'
 res = iter(varstr)
 r = range(1, 5)
 ​
 # isinstance() 检测一个数据是不是一个指定的类型
 # Iterable: 迭代对象,Iterator: 迭代器
 r1 = isinstance(varstr, Iterable)
 r2 = isinstance(varstr, Iterator)
 r3 = isinstance(res, Iterable)
 r4 = isinstance(res, Iterator)
 r5 = isinstance(r, Iterable)
 r6 = isinstance(r, Iterator)
 ​
 print(f'varstr 是迭代对象:{r1}, \t varstr 是迭代器: {r2}')
 print(f'res 是迭代对象:{r3}, \t res 是迭代器: {r4}')
 print(f'r 是迭代对象:{r5}, \t r 是迭代器: {r6}')
 ​
 ​
 # 执行结果
 varstr 是迭代对象:True, varstr 是迭代器: False
 res 是迭代对象:True, res 是迭代器: True
 r 是迭代对象:True, r 是迭代器: False

今天的知识点讲到这就结束了,接下来,让我们来做两个小练习。

练习题

递归查询斐波那契数列位数

还记得我们之前讲过的斐波那契数列吗?不记得没关系,我们来复习一下:

 # 斐波那契数列: 0, 1, 1, 2, 3, 5, 8, 13...

我们这次来实现一个函数,用于查询斐波那契数列中当前位置的数值是多少。

 # 递归实现斐波那契数列
 def fibonacci(n):
     if n == 1:
         return 0
     elif n == 2 or n == 3:
         return 1
     else:
         return fibonacci(n-1) + fibonacci(n-2)
     
 res = fibonacci(6)
 print(res)
 ​
 # 执行结果
 5

我为大家画了张图,来看看程序内部到底做了些什么:

raw-image

从这张图中,我们可以看到递归的步骤和返回的结果。

递归实现阶乘

什么是阶乘?比如我们实现7的阶乘,那么就是

raw-image

让我们来试着实现一下:

 # 实现阶乘
 def factorial(n):
     if n == 1:
         return 1
     else:
         return n*factorial(n-1)
     
 res = factorial(7)
 print(res)
 ​
 # 执行结果
 5040

验证一下看看:

 print(1*2*3*4*5*6*7)
 ​
 # 执行结果
 5040

看来结果没问题,那让我们来看看程序内发生了什么:

 '''
 factorial(7) =>
 7 * factorial(6) =>
    6 * factorial(5) =>
        5 * factorial(4) =>
            4 * factorial(3) =>
                3 * factorial(2) =>
                    2 * factorial(1) =>
                        factorial(1) = 1
                    2 * 1 = 2
                3 * 2 = 6
            4 * 6 = 24
        5 * 24 = 120
    6 * 120 = 720
 7 * 720 = 5040
 '''

虽然实现了,最后还是不得不说几点注意事项:

递归函数的效率并不高,所以尽量能不用就不要用。

一个函数如果调用后没有结束,那么栈空间中就一直存在,直到这个函数运算结束才会销毁。

好了,今天的课程到此结束。大家课后记得多练习。下课!

留言
avatar-img
留言分享你的想法!
avatar-img
茶桁的沙龍
9會員
62內容數
从基础开始,再到Python,然后是CV、BI、NLP等相关技术。从头到尾详细的教授一边人工智能。
茶桁的沙龍的其他內容
2023/08/22
虽然是最后一节课了,但是本节课的任务却是一点也不轻松。相比较而言,如果你以后从事的是数据治理和分析工作,那么本节课的内容可能会是你在今后工作中用到的最多的内容。我们需要学习行列索引的操作,数据的处理,数据的合并,多层索引,时间序列,数据的分组聚合(重点)。最后,我们会有一个案例的展示。
Thumbnail
2023/08/22
虽然是最后一节课了,但是本节课的任务却是一点也不轻松。相比较而言,如果你以后从事的是数据治理和分析工作,那么本节课的内容可能会是你在今后工作中用到的最多的内容。我们需要学习行列索引的操作,数据的处理,数据的合并,多层索引,时间序列,数据的分组聚合(重点)。最后,我们会有一个案例的展示。
Thumbnail
2023/08/21
Hi,大家好。我是茶桁。 上一节课中,我们学习了matplotlib. 实际上,我们已经进入了数据可视化阶段。 可是在上一节课中,所有的数据都是我们固定写好的,包括两个电影的数据展示的案例(柱状图和直方图),都是我们将数据手动写成了数据列表,然后直接使用。 在我们平时的工作中,不太有那么多的机
Thumbnail
2023/08/21
Hi,大家好。我是茶桁。 上一节课中,我们学习了matplotlib. 实际上,我们已经进入了数据可视化阶段。 可是在上一节课中,所有的数据都是我们固定写好的,包括两个电影的数据展示的案例(柱状图和直方图),都是我们将数据手动写成了数据列表,然后直接使用。 在我们平时的工作中,不太有那么多的机
Thumbnail
2023/08/21
Hi, 大家好。我是茶桁。 在上一节课中,我们结束了Python正式的所有内容,但是咱们的Python课程还未结束。从这节课开始,我们要来学习一下Python的第三方库。 Python的生态非常完善也非常活跃,我们不太可能讲目前所有的第三方库全部都介绍一遍,只介绍几个有影响力并且和处理数据相关的
Thumbnail
2023/08/21
Hi, 大家好。我是茶桁。 在上一节课中,我们结束了Python正式的所有内容,但是咱们的Python课程还未结束。从这节课开始,我们要来学习一下Python的第三方库。 Python的生态非常完善也非常活跃,我们不太可能讲目前所有的第三方库全部都介绍一遍,只介绍几个有影响力并且和处理数据相关的
Thumbnail
看更多
你可能也想看
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
在流程控制中,最常用的就是for loop 或是 while loop 語法了。 最常見的場景就是根據條件判斷式,重複執行特定的指令。 如果要在python寫出類似C/C++ for loop,可以怎麼寫呢? 透過索引去進行迭代 for var in range( start=0, sto
Thumbnail
在流程控制中,最常用的就是for loop 或是 while loop 語法了。 最常見的場景就是根據條件判斷式,重複執行特定的指令。 如果要在python寫出類似C/C++ for loop,可以怎麼寫呢? 透過索引去進行迭代 for var in range( start=0, sto
Thumbnail
sort reverse count index copy len min max sum any all
Thumbnail
sort reverse count index copy len min max sum any all
Thumbnail
這題乍看之下是新題目,但仔細一想, 其實只是前面介紹過的費式數列的小變形而已,解題思想基本不變。 題目說每次可以爬一階樓梯或兩階樓梯,問爬到n階的方法數是多少。
Thumbnail
這題乍看之下是新題目,但仔細一想, 其實只是前面介紹過的費式數列的小變形而已,解題思想基本不變。 題目說每次可以爬一階樓梯或兩階樓梯,問爬到n階的方法數是多少。
Thumbnail
Hi, 大家好。我是茶桁。 前几节课中我们学习了函数,那么这节课开始,我们花几节课返过头来详细的学习一下Python内的数据类型。第一节课,让我们先从字符串开始: 回顾字符串的定义方式 了解转义字符 字符串格式化的方法 字符串相关函数 字符串的定义方式 单引号定义字符串 ‘ ’ 双引
Thumbnail
Hi, 大家好。我是茶桁。 前几节课中我们学习了函数,那么这节课开始,我们花几节课返过头来详细的学习一下Python内的数据类型。第一节课,让我们先从字符串开始: 回顾字符串的定义方式 了解转义字符 字符串格式化的方法 字符串相关函数 字符串的定义方式 单引号定义字符串 ‘ ’ 双引
Thumbnail
Hi,大家好。 我是茶桁。 本节课,我们来学习一下Python中的「高阶函数」。 让我们先来了解一下,什么是递归函数。 递归函数就是定义一个函数,然后在此函数内,自己调用自己。 既然是自己调用自己,那这个函数必须要有一个结束才行,否则会一直重复的调用下去,直到调用层数越来越多,最
Thumbnail
Hi,大家好。 我是茶桁。 本节课,我们来学习一下Python中的「高阶函数」。 让我们先来了解一下,什么是递归函数。 递归函数就是定义一个函数,然后在此函数内,自己调用自己。 既然是自己调用自己,那这个函数必须要有一个结束才行,否则会一直重复的调用下去,直到调用层数越来越多,最
Thumbnail
Hi,大家好。我是茶桁。 在前面几节课的基础之上,我们今天开始尝试在Python中控制流程。这中间,让我们来做一些实际的练习。 Python语句的分类 让我们先了解一下Python语句的分类。 在Python中,可分为单行代码和代码块/组, 顾名思义,单行代码就是一行的Python代码,而代
Thumbnail
Hi,大家好。我是茶桁。 在前面几节课的基础之上,我们今天开始尝试在Python中控制流程。这中间,让我们来做一些实际的练习。 Python语句的分类 让我们先了解一下Python语句的分类。 在Python中,可分为单行代码和代码块/组, 顾名思义,单行代码就是一行的Python代码,而代
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News