抽象,自定义函数,递归

6.1懒惰是一种美德

如果你 在一个地方编写了一些代码,但需要在另一个地方再次使用,该如何办呢?

假设你编写了一段代码,它计算一些斐波那契数(一种数列,其中每个数都是前两个数的和)。

现在的数列包含10个斐波那契数。

如果要使用这些数字做其他事情,该如何办呢?我们肯定不愿意再重新写一遍代码。我们可以让程序更抽象。要让前面的程序更抽象,可以像下面这样做:

大家可以看见,我在确定num后直接可以打印出fibs。其实如果把整体封装起来,就可以直接调用。

6.2抽象和结构 

抽象可节省人力,但实际上还有个更重要的优点:抽象是程序能够被人理解的关键所在。

人和计算机的差别在于,计算机本身喜欢具体而明确的指 令,但人通常不是这样的。

例如:如果你向人打听怎么去电影院,就不希望对方回答:“向前走10步,向左转90度,接着走5步,再向右转45度,然后走123步。”(这是计算机希望听见的)。“沿这条街往前走,看到过街天桥后走到马路对面,电影院就在你左边。”(这是人希望听见的)。这里的关键是你知道如何沿街往前走,也知道如何过天桥,因此不需要有关这些方面的具体说明。

组织计算机程序时,你也采取类似的方式。程序应非常抽象,如下载网页、计算使用频率、打印每个单词的使用频率。

看到这些代码,任何人都知道这个程序是做什么的。但是其中到底如何做,其中的细节会在其他地方给出。

6.3自定义函数

函数执行特定的操作并返回一个值,你可以调用它(调用时可能需要提供一些参数——放在圆括号中的内容)。一般而言,要判断某个对象是否可调用,可使用内置函数callable。

此时说明x是不可以调用的,y是可以的。(并非所有的函数都返回值)

函数是结构化编程的核心。那么如何定义函数呢?使用def(表示定义函数)语句。

上面两行是对于函数的简单定义,最下面是对函数的调用。

 那现在回到斐波那契数,如果编写一个函数,返回一个由斐波那契数组成的列表呢?

前5行都是对于斐波那契数整个函数的定义,最后一行是对其进行调用。

其实我们不难发现,除了def一直需要外,我们在每个定义def中都有一个return语句。return语 句用于从函数返回值(在前面的hello函数中,return语句的作用也是一样的)。

6.3.1给函数编写文档

要给函数编写文档,以确保其他人能够理解,可添加注释(以#打头的内容)。

放在函数开头的字符串称为文档字符串(docstring),将作为函数的一部分存储起来。

代码前三行是定义,其中包含了我们的注释。最后一行我们先是调用了下函数进行计算,同时也读取了函数定义的文档字符串。(注意 __doc__是函数的一个属性。)

特殊的内置函数help很有用。在交互式解释器中,可使用它获取有关函数的信息,其中包含函数的文档字符串。

6.3.2其实并不是函数的函数

数学意义上的函数总是返回根据参数计算得到的结果。在Python中,有些函数什么都不返回。

什么都不返回的函数不包含return语句,或者包含return语句,但没有在return后面指定值。

这里虽然包含了return,但是其实return部分没有返回任何值,只是为了结束语句(第二个打印的go没有打印出来)(这有点像在循环中使用break,但跳出的是函数)

6.4参数魔法

函数使用起来很简单,创建起来也不那么复杂,但要习惯参数的工作原理就不那么容易了。

6.4.1值从哪里来

定义函数时,你可能心存疑虑:参数的值是怎么来的呢?

编写函数旨在为当前程序(甚至其他程序)提供服务,你的职责是确保它在提供的参数正确时完成任务,并在参数不对时以显而易见的方式失败。参数通常不需要担心。

在def语句中,位于函数名后面的变量通常称为形参,而调用函数时提供的值称为实参。很多情况下我们会将实参称为值,以便将其与类似于变量的形参区分开来。

6.4.2我能修改参数吗

参数不过是变量而已,行为与你预期的完全相同。在函数内部给参数赋值对外部没有任何影响。

在try_to_change内,将新值赋给了参数n,但如你所见,这对变量name没有影响。说到底,这是一个完全不同的变量。

这样可能更加直观,在有返回值的情况下,在定义里面修改参数会导致返回值的变化,但是但是重要的是它不会去修改我们的name。变量n变了,但变量name没变。同样,在函数内部重新关联参数(即给它赋值)时,函数外部的变量不受影响(参数存储在局部作用域内)。

字符串(以及数和元组)是不可变的(immutable),这意味着你不能修改它们(即只能替换为新值)。因此这些类型作为参数没什么可说的。但如果参数为可变的数据结构(如列表)呢?

唉?例子也是在函数内修改了参数,为什么函数外部的names发生变化了?大家先看下面:

这样的情况大家应该都见过,将同一个列表赋给两个变量时,这两个变量将同时指向这个列表。就这么简单。

这就解释了为什么在函数外的结果被修改了。

要避免这样的结果,必须创建列表的副本。对序列执行切片操作时,返回的切片都是副本。因此,如果你创建覆盖整个列表的切片,得到的将是列表的副本。

此时就可以发现,n和names虽然内容相同,但是已经不是同一个列表了。 注意到参数n包含的是副本。

(1)为何要修改参数

在提高程序的抽象程度方面,使用函数来修改数据结构(如列表或字典)是一种不错的方式。

假设你要编写一个程序,让它存储姓名,并让用户能够根据名字、中间名或 姓找人。为此,你可能使用一个类似于下面的数据结构:

每个键下都存储了一个人员列表。在这个例子里,这些列表只包含作者。

现在,要获取中间名为Lie的人员名单,可像下面这样做:

但是,如你所见,将人员添加到这个数据结构中有点繁琐,在多个人的名字、中间名或姓相同时尤其如此,因为在这种情况下需要对存储在名字、中间名或姓下的列表进行扩展。

下面来添加我的妹妹,并假设我们不知道数据库中存储了什么内容。

storage['first']['Anne'] 在第一个代码的第二行给first键对应的‘Anne’键对应的值用my_sister添加,由于之前我们并没有对Anne的键对应相应的值,现在直接添加,形成的结果就是刚刚添加的。对于三行的Lie之前我们有设置过值,现在append一个,最后得到的结果就是第二个代码出现的结果。

可以想见,编写充斥着这种更新的大型程序时,代码将很快变得混乱不堪。

抽象的关键在于隐藏所有的更新细节,为此可使用函数。下面首先来创建一个初始化数据结构的函数。

你所见,这个函数承担了初始化职责,让代码的可读性高了很多。

接下来设计获取人员姓名的函数。

第一个代码就是获取设计人员姓名的函数。第二个代码最后就是对该函数的使用。

下面来编写将人员存储到数据结构中的函数。

运行一下:

如你所见,如果多个人的名字、中间名或姓相同,可同时获取这些人员。

(2)如果参数是不可变的

在很多语言中,经常需要给参数赋值并让这种修改影响函数外部的变量。在Python中,没法直接这样做,只能修改参数对象本身。

但是,如果参数不可变呢?没办法。在这种情况下,应从函数返回所有需要的值(如果需要返回多个值,就以元组的方式返回它们)。

这样没有进过修改参数

如果一定要修改参数,改变外部的值,可以把值放在列表中。

6.4.3关键字参数和默认值

有时候,参数的排列顺序可能难以记住,尤其是参数很多时。

但是当我们改成这样的时候参数的顺序就无关紧要了,但是名称变的很重要。

像这样使用名称指定的参数称为关键字参数,主要优点是有助于澄清各个参数的作用。

虽然这样做的输入量多些,但每个参数的作用清晰明了。另外,参数的顺序错了也没关系。

然而,关键字参数最大的优点在于,可以指定默认值。

像这样,设定完默认值后,调用时不提供它,也可以运行出来。

当然也可以提供默认值。提供1个或者2个都可以。

如你所见,这两个提供的值,其实还是按照位置进行分配的。那如何使用提供的name或者greeting。

还不止这些。你可结合使用位置参数和关键字参数,但必须先指定所有的位置参数,否则解释器将不知道它们是哪个参数(即不知道参数对应的位置)。通常不会结合位置参数和关键字参数。

大家可以自己看一下代码,思考一下与预期是否相同。

直接运行报错,因为name没有设定默认值。

6.4.4收集参数

有时候,允许用户提供任意数量的参数很有用。

每次只能存储一个数据太少了,如果可以同时存储多个数据就比较好:

为此,应允许用户提供任意数量的姓名。请尝试使用下面这样的函数定义:

这里好像只指定了一个参数,但它前面有一个星号。

看,我们引用这个定义,发现最终打印出的是一个元组,因为里面有一个逗号。那继续尝试是否可以打印出更多的项。

看出来,打印多个项目也是可以的。参数前面的星号将提供的所有值都放在一个元组中,也就是将这些值收集起来。这样的行我们在5.2.1节见过:赋值时带星号的变量收集多余的值。它收集的是列表而不是元组中多余的值,但除此之外,这两种用法很像。

和我们预期相同,第一个参数收集一个值(params),第二个参数由于有*号,所以收集剩余的值(1,2,3)。

这段代码,在第一个参数收集完第一个值,没有值了,所以第二个参数返回了一个空的元组。

那此时,我们可能会好奇,那如果说星号的参数在中间,它应该怎么判断剩余的元组呢?我们尝试一下:

星号不会收集管自己参数,如果不给z=6呢?

报错了。

星号不会收集关键字参数。如下。

正常来说,在参数title收集到Hmm...后,剩余内容被星号参数收集,但是事实上没有,因为提供了关键字了,星号不会收集关键字参数。

要收集关键字参数,可使用两个星号。

如你所见,这样得到的是一个字典而不是元组。

将以上的内容全部结合一下,位置,关键字,*,**

现在我们来解决最初的问题,如何在姓名存储示例中使用这种技术?解决方案如下:

6.4.5分配参数

前面介绍了如何将参数收集到元组和字典中,但用同样的两个运算符(*和**)也可执行相反的操作。与收集参数相反的操作是什么呢?假设有如下函数:

现在定义了一个相加的函数,但是给出的两个数据在一个元组里。现在就希望将这两个数据进行相加,但是定义中给的是两个参数。与收集参数相反的操作(不是收集参数,而是分配参数):

当然使用一个*可以,也可以使用两个**。可将字典中的值分配给关键字参数。如下:

大家看下面这一段代码:

对于函数with_stars,我在定义和调用它时都使用了星号,而对于函数without_stars,我在定义和调用它时都没有使用,但这两种做法的效果相同。

因此,只有在定义函数(允许可变数量的参数)或调用函数时(拆分字典或序列)使用, 星号才能发挥作用。

使用这些拆分运算符来传递参数很有用,因为这样无需操心参数个数之类的问题,如下所示:

6.5作用域

变量到底是什么呢?可将其视为指向值的名称。因此,执行赋值语句x = 1后,名称x指向值1。这几乎与使用字典时一样(字典中的键指向值),只是你使用的是“看不见”的字典。

有一个名为vars的内置函数,它返回这个不可见的字典:

警告 一般而言,不应修改vars返回的字典,因为根据Python官方文档的说法,这 样做的结果是不确定的。换而言之,可能得不到你想要的结果。

这种“看不见的字典”称为命名空间或作用域。那么有多少个命名空间呢?除全局作用域外,每个函数调用都将创建一个。

这个地方就有些疑问了,我调用foo了,foo函数内赋值语句x=42,为什么最终x没有变化,依然是1呢?

这是因为调用foo时创建了一个新的命名空间,供foo中的代码块使用。赋值语句x = 42是在这个内部作用域(局部命名空间)中执行的,不影响外部(全局)作用域内的x。在函数内使用的变量称为局部变量(与之相对的是全局变量)。参数类似于局部变量,因此参数与全局变量同名不会有任何问题。

简而言之,就是创建函数foo时,创建了新的命名空间,这个空间里(局部)的x值不会影响到全局作用域中的x值。因此局部变量与全局变量同名也没有问题。

读取全局变量的值通常不会有问题,但还是存在出现问题的可能性。

(1)“遮盖”的问题

如果有一个局部 变量或参数与你要访问的全局变量同名,就无法直接访问全局变量,因为它被局部变量遮住了。(其实就是在局部变量里面使用全局变量时,如果局部变量中有与全局同名的,系统不知道识别哪一个,而因为在定义里面,会先访问局部变量)

那我到底如何让函数里知道我要访问全局变量呢?使用global

看,此时函数里就访问到了全局变量的parameter。

还记得我们在6.5开始的时候,函数里面的值的赋值操作,并没有改变函数外的值。那如何改变呢?

重新关联全局变量(使其指向新值)是另一码事。在函数内部给变量赋值时,该变量默认为局部变量,除非你明确地告诉Python它是全局变量。当然还是使用global。

ok,大家知道了可以这样进行关联全局变量。大家可以思考一下为什么下面这个x还是1呢?

(2)作用域嵌套

Python函数可以嵌套,即可将一个函数放在另一个函数内。

嵌套通常用处不大,但有一个很突出的用途:使用一个函数来创建另一个函数。这意味着可像下面这样编写函数:

在这里,一个函数位于另一个函数中,且外面的函数返回里面的函数。也就是返回一个函数,而不是调用它。重要的是,返回的函数能够访问其定义所在的作用域。换而言之,它携带着自己所在的环境(和相关的局部变量)!

每当外部函数被调用时,都将重新定义内部的函数,而变量factor的值也可能不同。由于Python的嵌套作用域,可在内部函数中访问这个来自外部局部作用域(multiplier)的变量,如下所示:

第一句中的2其实就是multiplier的factor,double中的5,其实就是number。下面两个例子也是类似的。

像multiplyByFactor这样存储其所在作用域的函数称为闭包。

通常,不能给外部作用域内的变量赋值,但如果一定要这样做,可使用关键字nonlocal。这个关键字的用法与global很像,让你能够给外部作用域(非全局作用域)内的变量赋值。

6.6递归

你知道,函数可调用其他函数,但可能让你感到惊 讶的是,函数还可调用自己。

如果你以前没有遇到这种情况,可能想知道递归是什么意思。简单地说,递归意味着引用(这里是调用)自身。(其实完全没有必要明白递归的准确定义)

这就是一个递归式函数的定义,其实什么都没做,与“递归”定义一样傻。

从理论上说,这个程序将 不断运行下去,但每次调用函数时,都将消耗一些内存。因此函数调用次数达到一定的程 度(且之前的函数调用未返回)后,将耗尽所有的内存空间,导致程序终止并显示错误消 息“超过最大递归深度”。

这个函数中的递归称为无穷递归(就像以while True打头且不包含break和return语句的循环被称为无限循环一样),因为它从理论上说永远不会结束。

我们需要的是对我们有帮助的递归,通常包含两个部分:

基线条件(针对最小的问题):满足这种条件时函数将直接返回一个值。

递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分。

6.6.1 阶乘与幂(经典案例)

首先,假设你要计算数字n的阶乘。n的阶乘为n × (n - 1) × (n - 2) × … × 1,在数学领域的用途非常广泛。

首先将result设置为n,再将其依次乘以1到n - 1的每个数字,最后返回result。但如果你愿意,可采取不同的做法。

ok,上面这个方法就一步步的进行计算,但我们也可以采用不同的方法。

①1的阶乘为1。

②对于大于1的数字n,其阶乘为n - 1的阶乘再乘以n。这与阶乘的定义相同。

再来看一个示例。假设你要计算幂,就像内置函数pow和运算符**所做的那样。要定义一个数字的整数次幂,有多种方式,但先来看一个简单的定义:power(x, n)(x的n次幂)是将数字x自乘n - 1次的结果,即将n个x相乘的结果。

同样,也可以将他改成递归式。

①对于任何数字x,power(x, 0)都为1。

②n>0时,power(x, n)为power(x, n-1)与x的乘积。

提示 如果函数或算法复杂难懂,在实现前用自己的话进行明确的定义将大有裨益。以这种“准编程语言”编写的程序通常称为伪代码。

那么使用递归有何意义呢?难道不能转而使用循环吗?答案是肯定的,而且在大多数情况下,使用循环的效率可能更高。然而,在很多情况下,使用递归的可读性更高,且有时要高得多,在你理解了函数的递归式定义时尤其如此。

6.6.2二分查找

例如,对方心里想着一个1~100的数字,你必须猜出是哪个。当然,猜100次肯定猜对,但最少需要猜多少次呢?实际上只需猜7次。首先问:“这个数字大于50吗?”如果答案是肯定的,再问:“这个数字大于75吗?”不断将可能的区间减半,直到猜对为止。你无需过多地思考就能成功。

这样的想法适用于众多其他不同的情形。

一个常见的问题是:指定的数字是否包含在已排序的序列中?如果包含,在什么位置?为解决这个问题,可采取同样的策略:“这个数字是否在序列中央的右边?”如果答案是否定的,再问:“它是否在序列的第二个四分之一区间内(左半部分的右边)?”依此类推。明确数字所处区间的上限和下限,并且每一个问题都将区间分成两半。

这里的关键是,这种算法自然而然地引出了递归式定义和实现。

①如果上限和下限相同,就说明它们都指向数字所在的位置,因此将这个数字返回。

②否则,找出区间的中间位置(上限和下限的平均值),再确定数字在左半部分还是右 半部分。然后在继续在数字所在的那部分中查找。

在这个递归案例中,关键在于元素是经过排序的。找出中间的元素后,只需将其与要查找的数字进行比较即可

当然,上面的代码有一个缺陷,在一我们通常不知道lower和upper(这两个值代表的是列表的下标)所有可以进行修改。

现在进行调用,看是否正确。

结果是正确的,但是你可能会好奇,明明对于列表,我们可以直接index查找,为什么要这样呢?

的确,index是可以的,但是效率太低了,前面说过,要在100个数字中找到指定的数字,只需问7次;但使用循环时,在最糟的情况下需要问100次。(大家看100好像没什么,事实上,在可观察到的宇宙中,包含的粒子数大约为10 87个。要找出其中的一个粒子,只需问大约290次!)

实际上,模块bisect提供了标准的二分查找实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记96:前馈控制 + 航向误差

1. 回顾 对于一个 系统而言,结构可以画作: 如果采用 这样的控制策略,结构可以画作:(这就是LQR控制) 使用LQR控制器,可以通过公式 和 构建一个完美的负反馈系统; a a 但是有上…

解密智慧校园解决方案:赋能数字化教育的未来

在当今数字化时代,智慧校园解决方案正以惊人的速度改变着教育界的面貌。随着科技的快速发展,数字化教育已经逐渐成为现代教育的核心。智慧校园解决方案作为一个集技术、教育和创新于一体的综合性项目,为学校提供了许多机遇和挑战。本文将揭示…

遇见桂林山水画廊,深层互联自动讲解耳机走进漓江

遇见山水,听懂山水。由深层互联独家打造,桂林漓江山水画廊导览工程,于不久前正式启动,声情并茂的真人语音引导着游客,走进有声有色的山水画卷中。 桂林山水甲天下,得天独厚的自然景观,奇幻瑰丽…

掌握4种常见电脑视频压缩方法,轻松解决空间危机

在现今数字化的时代,视频成为我们生活和工作中不可或缺的一部分。然而,随着高清、超高清视频的普及,视频文件的大小也随之增大,给存储、传输和分享带来了一定的挑战。为了克服这一问题,电脑视频压缩成为一项关键的技术…

SwiftUI获取用户的位置信息(CLLocationManager,CLLocationManagerDelegate)

本篇文章将会介绍一下在SwiftUI中如何通过CorLocation框架获取用户的位置信息,因为获取位置信息属于用户的隐私信息,所以需要在Info.plist文件里面加上访问位置权限的说明。 关于位置信息,可以请求两种级别的许可:always和when i…

视频剪辑去水印软件推荐 视频剪辑去水印方法

不会去水印,很难做好视频剪辑。选对软件、掌握去水印的方法,是每个剪辑师必须经历的过程。真正擅长视频剪辑去水印的软件,一定具备多种去水印功能。剪辑师可以根据素材的具体情况,选择最恰当的去水印方法。有关视频剪辑去水印软件…

JimuReport 积木报表 v1.7.5 版本发布,免费的低代码报表

项目介绍 一款免费的数据可视化报表工具,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等! Web 版报表设计器,类似于excel操作风格,通过拖拽完…

【日记】遇到了一个很奇怪的大爷(845 字)

正文 花了昨天和今天两天时间,把数据转移完了。这块 2T 的硬盘可以光荣退休了。目前是没什么存储焦虑了。 农发行净开发一些垃圾系统。今天没什么业务,但跟 ActiveX 斗智斗勇了一整天,最后实在搞不过 IE 浏览器。我也懒得管了,又不…

禁用layui树形表格的多选框checkbox

1. 背景 在使用树形表格渲染数据时,需要对数据进行批量操作。相对于选中数据后,再做错误提示。直接把数据的多选框禁用掉更加直观。 2. 实现 DisabledTableCheckBox: () > {// 获取所有行 var tableElem $(".layui-table-fixed-l");var …

一脉阳光上市圆梦:销售成本高昂,两大创始人的行贿往事与屡屡被罚

《港湾商业观察》施子夫 2024年6月7日,江西一脉阳光集团股份有限公司(以下简称,一脉阳光)将正式在港交所主板挂牌上市(以下简称,一脉阳光;股票代码02522.HK),公司预计发…

Vue3【七】setup的语法糖setup简写方法

Vue3【七】setup的语法糖setup简写方法 Vue3【七】setup的语法糖setup简写方法 使用script标签式写法称为setup语法糖 组件名称默认位文件名 export 的内容可以省略 案例截图 案例目录 案例代码 Person.vue <template><div class"person"><h1>我…

这才是计科之 Onix XV6 源码分析(1、XV6-x86的启动)

这才是计科之 Onix & XV6 源码分析&#xff08;1、XV6-x86的启动&#xff09; 前言 Onix是一款相对于XV6来说功能更为健全的单核OS&#xff0c;由于功能更加完善&#xff0c;Onix也更加复杂。代码阅读起来会比较绕。 XV6是一款简单易读的多核操作系统&#xff0c;但其功…

【JMeter接口测试工具】第一节.JMeter简介和安装【入门篇】

文章目录 前言一、JMeter简介 1.1 JMeter基本介绍 1.2 JMeter优缺点二、JMeter安装 2.1 JMeter安装步骤 2.2 JMeter环境配置三、项目介绍 3.1 项目简介 3.2 API接口清单总结 前言 一、JMeter简介 1.1 JMeter基本介绍 JMeter 是 Apache 组织使用…

java---程序逻辑控制(详解)

目录 一、概述二、顺序结构三、分支结构3.1 if语句3.1.1 语法格式13.1.2 语法格式23.1.3 语法格式3 3.2 练习3.2.1 判断一个数字是奇数还是偶数3.2.2 判断一个数字是正数&#xff0c;负数&#xff0c;还是零3.2.3 判断一个年份是否为闰年 3.3.switch语句 四、循环结构4.1 while…

Flutter vscode环境如何进行真机测试

目录 1. 准备工作 1.1 安装Flutter和VS Code 1.2 安装必要的VS Code扩展 1.3 手机设置 2. 配置VS Code调试环境 3. 手机如何退出开发者模式 1. 准备工作 1.1 安装Flutter和VS Code 确保你已经在电脑上安装了Flutter SDK和VS Code。如果还没有&#xff0c;可以参考以下指…

项目文章 | Nature Commun蓝藻转录因子PhoB对磷/铁的营养元素限制的调控机制

近日&#xff0c;华中师范大学邱保胜教授团队在《Nature Communications》发表题为“Phosphorus deficiency alleviates iron limitation in Synechocystis cyanobacteria through direct PhoB-mediated gene regulation”文章&#xff0c;其重点研究了Synechocystis蓝藻转录因…

硬件产品经理

边端协调管理平台 主页模型管理配置管理设备管理设备检测组态数据服务传输通道服务 定义与范围&#xff1a; 边测&#xff1a;通常指的是边缘计算的测试&#xff0c;这里的“边缘”可以理解为离用户更近的计算节点或设备&#xff0c;如小 型数据中心、具有计算能力的小基站等。…

深度学习课程设计:构建未来的教育蓝图

深度学习课程设计&#xff1a;构建未来的教育蓝图 在近年来&#xff0c;深度学习已经从一项前沿的技术发展成为计算机科学领域不可或缺的一部分。随着其在多个行业中的应用日益增多&#xff0c;对深度学习教育的需求也在急剧上升。对于计划将深度学习纳入学术课程的教育者而言…

【WRF理论第二期】运行模型的基础知识

WRF理论第二期&#xff1a;运行模型的基础知识 1 Basics for Running the Model2 Geogrid程序2.1 Geogrid2.2 Terrestrial Input Data 3 Ungrid程序3.1 Ungrid3.2 Intermediate Files3.3 Required Fields 4 Metgrid程序参考 官方介绍-Basics for Running the Model 本博客主要…

耐用好用充电宝有哪些?畅销排行榜前四款充电宝推荐

在日常生活中&#xff0c;一款耐用且好用的充电宝是我们出行必备的利器&#xff0c;它可以为我们的手机、平板等设备提供持续的电力支持。然而&#xff0c;在市面上琳琅满目的充电宝品牌中&#xff0c;究竟哪些才是真正耐用又好用的选择&#xff1f;为了帮助大家更好地了解市场…