干货 | 清华大学学生大数据协会&软创协会Python系列讲座(第一期)

2023-11-10 16:15:22 浏览数 (1)

以下内容整理自清华大学学生大数据协会&软创协会举办的Python系列线上讲座第一期。

Python编程入门

大家好,我是软件学院科协技术部的许霖,今天给大介绍一些Python的基础语法。

首先,我先引入一些预备知识。Python这门程序语言非常突出的特点就是相对比较简洁易学,并且生态丰富,特别是在ChatGPT爆火之后,它已经逐渐成为现在最热门的程序语言之一。右边这张图是一个程序语言的网站stack overflow公布2022年最受欢迎的程序语言排名,Python位于第4位,现在应该远高于这个位次。Python在很多领域都有比较大的用处,比如数据分析、数据挖掘、人工智能。因为Python代码比较简洁,如果用Python来开发人工智能,开发者可以更好地把重点放在算法上,不需要浪费太多时间关注底层细节。还有互联网开发、自动化办公、爬虫等等都会用到Python语言。

Python这门语言相对于别的编程语言有哪些优点呢?第一个就是代码比较简洁易懂,所以非常容易入门。比如我们看右边这里对比的C 和Python实现的字符串的分割, C 里面要引入 string vector等等头文件,写一大串才能够把任务完成,而Python直接一句result=src.split()就可以很简洁的把它写出来了。

这样可以让开发人员专注于实现程序的功能,专注于一些算法,而不需要浪费太多时间在很底层的细节上。再一点是Python有比较强大的内置库和丰富的第三方库,它的社区生态比较良好,很多之前写Python的人已经把一些轮子给我们造好了,我们只需要直接拿来用就行了。Python的可移植性和可拓展性比较好,如果我们之前写过C 的话,应该知道C 在一个机子上编译的exe文件,放到别人的电脑上没办法运行,而Python因为它是以源码发布的,所以不管在什么机子上,只要它装了Python的解释器,都可以运行。

但是万物有得并有失,Python有它的一些缺点。第一个是运行速度相对于c 和Java确实比较慢。它是一门解释型语言,会边解释边执行,拖慢效率。相对来讲也缺乏足够的安全检查,当执行碰到歧义的时候,机器会倾向于去想办法解释它,而不是报错,所以有时可能Python写错了,也会照章执行,但就是不知道错在哪,导致后面很难找到bug。

怎么去写Python?首先要把Python安装下来,进入官网https://www.python.org/,选择自己要下载的类型, windows还是MAC,要注意的是Python有2.0和3.0两个版本,要选择3.0的版本。接下来基本上是傻瓜式的操作,直接按 next就可以。等到大家安装完之后,可以试一下在命令行里面输入一下Python,如果出现了类似于右图的这样一些文字,说明安装成功。

但是这一步完成之后,也仅仅是把 Python的解释器给安装下来了。如果要写Python的话,其实还不够,因为Python自带的开发环境是比较的拉垮的,所以我们一般推荐使用 PyCharm进行代码书写, PyCharm可以直接点官网下载即可,学生可以进行认证,不需要再额外花钱。

安装好之后,新建项目new project,选择好Python的环境,然后手动选择一下Python的位置,就可以写Python的代码了。运行调试这些应该都是比较简单的一些东西,网上的教程也比较多,所以我这里就不详细讲。除了Python之外,还有一些其他的开发环境,比如vs code等等,我接下来会主要用vs code给大家进行演示。

现在开始说一下 Python的一些基本语法。首先,学习一个程序语言的时候,一般第一步都是输出hello word。首先是if __name__==”int __main__”,这样一个语句是表示程序的入口,类似于C 里面的int main。也就是说这个程序不管写了多少,它在执行的时候会首先找到if __name__==”int __main__”,然后开始执行底下的程序,这里要注意一下name,它前后都是两个下划线,然后main的前后也是两个下划线,不要漏掉。

接下来会换行print(“hello word”),这里的print就是打印就是在屏幕上面输出的意思,我们会在双引号内写上我们要输出的内容。注意一点,我们在写print(“hello word”)的时候,前面要进行缩进,这个是Python的语法要求,如果缩进代表的是上面这一行if __name__==”int __main__”会管下面这一个 print(“hello word”)。如果不缩进的话,它表示这两个语句是同一个层级的,那么这句print(“hello word”)不一定会执行。

我们现在来拿 vs code来演示一下,我们看到在这个程序里面它在这里输出了一个 hello word。大家可以看到我代码当中有一些绿色字体,这些东西并不是解释器会执行的代码,而是被我们称为注释。所谓注释就是给人看的,帮助人去理解这一段代码到底在写什么,而机器只会执行这些在注释之外的东西。

在Python里面一般注释有两种格式,一种是先打一个#,#后面的话写上一行关于这段代码的解释,另外一种是输入三个”””,然后开始写注释,一直等到下一次输出三个引号的地方结束。

这里说到Python语法的基本原则。Python是以换行符作为两条语句的风格标志的,在刚才我们这样一段代码里面,如果不换行,程序会报错。Python会使用缩进来代表代码的层次结构,比如说我们这里print(“hello world”)隶属于前面这一句if __name__==”int __main__”。然后对比C语言,它会用“;”来表示语义的分隔符,而缩进是不表示含义的,只是为了方便阅读。

接下来我们说到变量。所谓变量就是我们在程序当中为一些数据起了一个名字。在程序设计语言当中变量有很多种类型,常见的有:整型数类型,int表示的是整数,比如说012345、-1、-2、-3等,我们称之为叫整型数类型,然后缩写是int;第二种是浮点数类型,可以简单地把浮点数理解成小数,表示的是各种各样的小数;第三个是布尔型的量,布尔型的量用来表示一个事情是对还是错,它只有两种类型,它只有两种量,一个是true表示真,然后false表示假,还有 string这种类型,表示的是一串字符。

接下来这一段代码当中,第一句n=1.2e2,这一段代码表示声明了一个变量,叫做n。然后把1.2e2赋值给了n,所以现在n就代表1.2e2,这里要说明的是“=”跟我们数学上的“=”表示的不太一样,数学上的“=”表示左右两边的量是相等的,但是我们程序语言里面的“=”是把右边的代数式的值赋给左边,比如在这里就是我们把1.2e2赋给了变量n,再比如下面的f=0.25,就是我们声明了一个变量叫f,然后把0.25赋值给了它。n跟f两个都属于浮点数类型。

Python在声明变量的时候,不用直接声明数据类型,因为解释器会自动根据赋予它的值去推断它到底是属于整型数还是属于浮点数。下面这一句b=True,就是声明了一个变量b,把True赋给它。解释器也能推断出b是一个布尔值,它表示的是某一个事件到底是真还是假。最后这一句是L=[1,2,3,4,5],表示的是一个列表类型,这里声明了一个变量L,把右边的列表赋给了它。

接下来看一下分支结构。在生活当中,我们经常会面对这样一种情况,针对一个事情不同的可能性,会采取不同的应对措施。比如说我在建华楼上课,可能下课之后会去兰园吃饭,如果在4教上课,可能下课之后会去丁香园吃饭。在Python当中,我们就使用分支结构去表示这种分情况讨论。分支结构一般来讲是使用if else这样一种语句去表示。举个例子,首先第一句是number=2,也就是声明了一个变量number,把2这样一个整型数赋给它,现在number就是2,接下来if number=1,它会检测if后面紧跟着这一句话的条件是否为true,如果为true的话,就会执行if对应的这一段所包含代码里面的内容,也就是print(‘ number equals 1’),如果不是的话就会跳过这一段,然后往下执行。在这里,if后面的条件是number=1。刚才我们说了“=“在我们程序语言里面表示的是附值,而不再表示数学上的等于,我们用两个“=“表示左右两边相等,这一句执行的就是if number=1,print会打印出括号里的内容。这里number=2,所以条件是false,这一句print(‘ number equals 1’)就不会去执行,它就会跳过来到下面一句。elif表示的是否则如果。我们刚执行了if number==1,如果number==1,否则如果number==2,我们print(‘ number equals 2’),它是在前面的条件已经被判定为假的情况下,如果后面这样一个条件成立,会做出什么事情。我们知道这里已经把number==1条件判为false,再看这里的if number==2发现它是对的,机器就会执行后面的print(‘ number equals 2’)。最后这一句else表示的是如果以上这几个number==1,elif number==2都是错的,会执行最后这一句,print(‘ number not equals 1or 2’),表示以上所有的条件都不正确的时候才轮到它去执行,这个程序运行的结果就应该是number equals 2。

实际上在我们正常应用的过程中,不一定非要写 if 、elif和else,代码的运用其实是相当的灵活的。我们可以直接写if number==1 print(‘ number equals 1’),后面的不写,从语法上来讲其实也是对的,此时if number==1条件不成立,就直接跳过了,这样也是可以的。我们也可以去写 if number==1 print(‘ number equals 1’),省略掉中间的elif语句,从语法上来讲也可以,只不过执行的时候它就会执行成if number==1不成立,直接执行下面else语句 print(‘ number not equals 1or 2’),虽然从逻辑上来讲不对,但是语法上来讲这些都是允许的,它的使用其实是相当的灵活的。

接下来我们讲循环结构。循环结构也就是让我们重复做某件事情的时候使用。比如我现在如果让你输出1的话,直接print(1)就可以了。如果我现在要让你把1~100全都输出出来,肯定不能写100条语句。这个时候我们就要运用到循环结构。一般来说循环结构有两种格式,一种是用while作为关键词,一种是用 for作为关键词。我们这里先讲 while它是怎么执行的。while所执行的顺序是,首先检测while后面的条件是否为真,如果为真的话,就会继续向后执行while所统属的代码,执行完之后再返回这一句while condition,再一次去执行检查这个condition是否满足,如果满足的话就继续执行,循环往复,直到突然不满足了,就会跳出这个程序。

我们来看一下图片中这一段代码,首先第一句stop=0,声明了一个整型的变量stop,赋值为0。接下来就开始执行while(stop<=4)。我们发现这个时候它是正确的,那么它就会执行while所统属的这一段代码,也就是print (‘not stopped yet!’),然后再执行 stop =1。这里的这句stop =1表示的就是stop 1,执行完这一句之后,它就跳回到while(stop<=4)。我们再检查我们发现现在stop=1,它还是<=4的,所以我们再去执行print (‘not stopped yet!’),把 stop再执行 1变成2,直到第五次执行的时候,stop现在变成了5,我们再跳回到while语句去检查,我们发现这时候stop它就不满足<=4的条件了,也就是说while后面的 condition是 false的时候,跳出来不再执行这个代码,直接开始print (‘stopped!’),所以我们这一段代码执行的结果应该是先输出5行”not stopped yet!”, 然后最后等到stop变成5的时候,它再把 ”stopped!”给输入出来。

接下来是 for结构,一般是这样写的, for i in range(4),这里要说明的是range一般用来表示一个整数的序列,range(4)用于生成一个从0直到3的整数序列。这里它所执行的顺序就是逐步把 range(4)里面的值赋给变量i。第一个值也就是0, 再print (i**2),就会输出0。等执行了之后,再返回到 for,会再一次把第二个值也就是1赋给 i,再去执行print (i**2)得到1,一直等到第四次的时候, i变成3,执行之后就不再去执行了。这一条语句有一个更简洁的写法,就是[print(i**2) for i in range(4)],这种写法也是可以的。这种写法的顺序可能比较容易搞糊涂,一般它的顺序是首先执行这里的for i in range(4),然后再执行前面的 print(i**2)。

还有一个数据类型是字符串类型,也就是string,字符串类型一般会用单引号或者双引号去把一个或多个字符包围起来。比如右边这里 st=‘t’就表示我现在声明了一个变量起名叫st,这个变量表示的是一个值为t的这样一个字符串。字符串可以直接使用 把它们给拼接起来。我们也可以使用 split()函数对字符串进行切分。比如说我们看底下这一句,说’Split this sentence by white space…’.split(‘ ’)。split()内引号之间隔了一个空格,这就表示空格这样一个字符串。这句话所描述的意思就是要把前面这句话的字符串按照空格给切分开,成为单独的词,然后生成一个单独的列表。

然后有人就要问了,有时候输出一个字符串的话,不仅仅是输出一个固定的语句,我们要输入的语句里面,可能会有一些不太确定的因素。比如我们现在这样一个例子里面,我们要说税款是多少,需要先把税收的总量计算出来,然后再放到字符串里面输出。我们有4个方法。

第一个,这里先是声明了money和rate这两个量,然后 tax_money就是把这两个量乘起来,得到应该上交的一个税款。我们用刚才说的“ ”来拼接print(‘tax is’ str(tax_money) ’.’),这里str()函数表示的是把数字转换成字符串的类型,我们知道这里的tax_money本来解释器推断的是等于50000*0.62,应该是一个浮点数的变量,再用“ ”就不对,因为“ ”的话我们是用来拼接一个字符串的,所以只能用str()这个函数把浮点数转换成字符串的类型,然后才能把它输用“ ”输出正确结果,这是第一种方法。

第二个做法是用格式化输出,把我们要输出 tax_money用花括号替代出来,等于是用花括号为我们要输出的 tax_money变量预留了一个位置,后面用上.format(tax_money),在输入的时候,把 tax_money对应的值填充到花括号里面去,然后再输出,也是符合我们的预期的。

现在不仅仅是想让它输出成这样的形式,希望能够输出精确到小数点后4位,我们就在原先格式化输出的花括号里面写上”:.2f”,这里的“:”仅仅是一个提示符,没有什么具体的含义。这里的“.2f”我们可以理解为保留了两位小数的一个浮点数,浮点数我们一般用float来表示,这里的f就是float的缩写。

最后还有一种格式化的输出方式,我们直接在括号里面先写上f,然后再写上这样的一个字符串,就不需要再用format了,直接把这里的tax_money写在花括号里面,然后再加上后面“:.2f”就可以把这个输入出来了。

还有一个常见的类型是列表类型。浮点数、字符串这些东西只是表示一个数据,如果我现在想要去表示1万个数据、1亿个数据,我们不可能去给1万个变量逐一命名,这个时候就要用到列表,列表给我们提供了一种高效的命名变量的一种手段。

比如我们现在执行了l=[1,2,’a’,3,6,”999”]这样一个语句,右边这里我建立了一个列表,这个列表赋给了l。我们注意到1、2、3、6这些属于整型的数据类型,而这里的a、999其实是属于我们刚才说的字符串类型。在Python的语法里面,可以用同一个列表去装不同类型的数据,与C 和Java有明显的区别。C 和Java的数组只能用来装同一个类型的数据,如果一个列表的第一个数据是整型数int,后面的所有东西都必须是 int,但是Python的话就显得更加灵活一些。

如果我们要去知道某一个列表的长度,我们可以用len()这个函数。我们会使用中括号进行索引。l[2]就是索引列表当中的第二个元素。刚刚第二个元素对应的是这个字符串a。然后这里我要解释一下, Python里面的列表的第一个元素一般是记成第0个元素,l[2]就对应的是这里的第3个元素a。列表还有其他的一些操作,比如切片,切片是通过操作取出子列表, l[2:5]表示的是把列表中的第二到第五个元素之间的元素取出来,作为一个子列表。这里要注意取值是前闭后开的,会取234三个元素,第五个元素是不取的。列表还支持其他的操作,比如把 list当中的第二个元素改成 b,可以直接写l[2]=b,这里就是把b这样一个字符串赋给第二个元素,再去输出l,就会得到[1,2,’b’,3,6,”999”]。要往列表里增加一些数据的话,可以使用append()函数,这个函数的作用就是在列表的尾巴上加东西。l.append(’d’)就是在999后面加了一个d,如果我们要在列表的中间增加一个元素,可以使用insert()函数去操作。

除此之外,还有我们还会稍微讲一下元组的类型。元组其实跟列表有一定的相似之处,也是用来连续储存若干个任意数据类型的数据的,但是元组类型(也就是tuple类型)的内容是不可修改的,所以我们称它为不可变序列。

有人可能就要问我创建了一个东西,我又不能修改它,比如它不是不如列表list类型,为什么我还要用它?是因为在写程序时,创建一些对象,要去考虑到之后在这个项目上的开发者会不会去修改这个东西,可能就会造成一些意外的结果。所以我们这里要强制规定不允许修改,因此引入元组这样的一个量。

元组的定义与列表不同,元组会使用()来进行,比如这里的 t=(‘python’,9, 0.25),我们就定义了一个元组,里面的数据是Python、9和0.25,t=tuple((‘python’,9, 0.25))这一段表达意思是一样的,对于它的索引,也是和刚才的列表相同,同样是用中括号进行索引。

总结一下,数据的类型主要有整型、float还有布尔类,然后字符串类型也就是string、列表类型list,然后原组类型tuple,还有一个字典类型,因为里面的操作相对来说比较复杂,所以我们这节课时间比较有限,就不细讲了,同学们可以自己课后的话去看一下它。

关于Python里面的一些四则运算和逻辑操作,加减乘除基本上都和C 是一样的。这里的乘我们一般用”*”来表示,除的话就用“/”来表示,逻辑操作与或非也很简单,就直接是英文的”and““or””not”。但是这里有一点与C 不太一样的地方, Python里面的“/”总是会计算真实的结果,比如让 Python输出1÷2,确实会输出0.5,与c语言是不一样的。c语言会根据分子和分母的类型来推断出结果的类型,然后再输出出来。如果在c语言里输出一个1÷2,由于分子分母都是整型数,所以最后会输出一个取整,也就是0,这一点的话Python和c语言是不一样的。Python里面的整除会用“//”去表示,如果1要去整除2的话,就跟c语言里面的除法是一样的,它会向下取整得到0。

前面说了Python的一些基本的数据结构,下面来讲一点点语法糖。所谓语法糖就是指计算机语言当中有一些特殊的语法,它的引入对于语言本身的功能可能没有什么特别大的影响,但是它在一般的语言的基础上做了一点点简化,这样会更有利于程序员去使用,有利于提高程序开发的效率,同时程序可读性会更加好。我们讲的第一个语法糖是关于它的变量交换。如果写过c语言的话,应该知道在c语言里面,如果要对于两个变量进行交换,要先声明一个变量temp,然后把a里面的值赋给temp,然后我们再把b里面的值赋给a,最后把temp里面的值赋给b。但是在Python里面其实很简单,我们直接写a,b=b,a就可以了。

Python里面第二个我们要介绍语法糖是它的链式比较,所谓链式比较是相对于我们在c语言里面不能进行链式比较来说的。我们都知道在c里面如果要表示40<a<60的话,不可以写40<a<60的,编译器会直接报错,只能写 a<60 and a>40,但是在Python里面就可以直接这样写,这就是一个比较大的化解。

还有一个是关于刚才的控制结构。现在要看一下分数如果>=60,把level等级记为p,否则记为f,如果做一些简化,可以把它写成level=‘p’ if grade >=60 else ‘f’。这段代码也是非常好理解的。还有一个是循环结构里面,我们刚才讲列表的增加,一开始建立一个空的列表l, i从0~4,不断把i的平方放到 list的后面,执行结果就是最后 l里面的数值变成了0、1、4、9、16,源代码可以把它简化成I=[i**2 for i in range(5)],开发效率也得到了比较大的提升。

以上就是今天讲座的所有的内容,谢谢大家。

编辑:于腾凯

校对:林亦霖

0 人点赞