写给 青少年的人工智能 实践

978-7-115-59088-6
作者: 核桃编程
译者:
编辑: 吴晋瑜

图书目录:

详情

这是一本写给青少年看的人工智能科普图书,目的是帮助青少年启蒙科学素养,开阔科学视野,培养科学思维,锻炼动手能力,让小读者了解人工智能的过去、现在和未来,从而更好地融入人工智能时代。通过阅读本书,小读者不仅能学习 Python 语言的基本使用,还可以从数据、算法等多个角度来一探人工智能的奥秘。所有这些都旨在激发孩子们的好奇心,帮助他们体会科学研究应具备的精神。 本书用了大量形象的比喻,用贴近青少年生活的案例作类比,把书中的抽象概念和难点以诙谐幽默的手绘插画形式诠释出来,力求让小读者读得懂、喜欢读。 本书从“如何实现人工智能”出发,讲述了最流行的人工智能编程语言之一—Python 语言的基本使用,帮助小读者初步学习一种获取数据的重要手段—网络爬虫,以及如何进行简单的数据处理,了解什么是算法,体验简单的人工智能算法,领略算法的魅力。当然,最终还会指导小读者一行行地亲手写出代码,在自己的计算机上运行自己写出的人工智能程序。全书从多个角度打开了人工智能的大门,让读者得以窥见门内的风景。

图书摘要

版权信息

书名:写给青少年的人工智能 实践

ISBN:978-7-115-59088-6

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

版  权

著    核桃编程

责任编辑 吴晋瑜

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e59088”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

内 容 提 要

这是一本写给青少年看的人工智能科普图书,目的是帮助青少年启蒙科学素养,开阔科学视野,培养科学思维,锻炼动手能力,让小读者了解人工智能的过去、现在和未来,从而更好地融入人工智能时代。通过阅读本书,小读者不仅能学习Python语言的基本使用,还可以从数据、算法等多个角度来一探人工智能的奥秘。所有这些都旨在激发孩子们的好奇心,帮助他们体会科学研究应具备的精神。

本书用了大量形象的比喻,用贴近青少年生活的案例作类比,把书中的抽象概念和难点以诙谐幽默的手绘插画形式诠释出来,力求让小读者读得懂、喜欢读。

本书从“如何实现人工智能”出发,讲述了最流行的人工智能编程语言之一——Python语言的基本使用,帮助小读者初步学习一种获取数据的重要手段——网络爬虫,学习如何进行简单的数据处理,了解什么是算法,体验简单的人工智能算法,领略算法的魅力。当然,最终还会指导小读者一行行地亲手写出代码,在计算机上运行自己写出的人工智能程序。全书从多个角度打开了人工智能的大门,让小读者得以窥见门内的风景。

参与本书编写的成员名单

内容总策划:曾鹏轩 王宇航

执行主编:庄 淼 丁倩玮 陈佳红 孔熹峻

插 画 师:闫佩瑶 林方彪 黄昱鑫 王晶宇

致小读者

小读者们,大家好!我是“核桃编程”的宇航老师。提到“人工智能”(AI),你会想到什么呢?是能听懂你说话的智能音箱语音助手,还是能打败围棋世界冠军的 AlphaGo?是无人驾驶汽车,还是科幻电影里的超能机器人?相信你一定会浮想联翩。人工智能已经渗入我们生活、学习中的方方面面。

为什么这些各不相同的东西都叫作“人工智能”?在《写给青少年的人工智能 起源》一书中,我们探讨了“什么是人工智能”,并沿着人类使用工具的历史,回顾了原始工具以及人工智能的开端——达特茅斯会议,细数了近几十年来人工智能领域的重要发明创造。

那么,科学家们又是怎样研究出这些人工智能产品的呢?在《写给青少年的人工智能 发展》一书中,我们仿佛“进入”了科学家的大脑,沿着他们研究问题的思路,“亲身经历”了人工智能发展的过程,并最终了解了几种常用的研究人工智能的思路:让机器学会推理,用机器构建大脑,让机器适应环境,等等。

经过几十年的努力,科学家们“八仙过海,各显神通”,研究出了各种各样的人工智能产品,将人工智能技术应用到了生活、医疗、艺术、农业、商业等领域。在《写给青少年的人工智能 应用》一书中,我们选取人工智能在各行各业典型而有趣的应用,让你了解现在的人工智能到底“智能”到了什么程度、“智能”体现在了哪些方面。

到这里,你应该对人工智能的起源、发展和应用有了一定的了解,有没有一种跃跃欲试想要参与其中的想法呢?别急,本书会带你动手试一试,引导你试着开发一些属于自己的人工智能程序,让你从实践中体会其奥妙。

最后,还要告诉你一件好玩儿的事。为了让小读者读得懂、喜欢读,我们把人工智能科学中不好理解的名词和概念,尽可能用形象的比喻或者贴近生活的类比加以解释,把抽象的知识点用风趣幽默的手绘插画加以诠释。插画中的这些角色可都是“核桃世界”的动漫明星呦,快去和他们打个招呼吧!

小读者们,快来开启你的人工智能启蒙之旅吧!

核桃编程联合创始人 王宇航

人工智能的身体

禾木:小核桃,快快快,我们开始创造人工智能吧!我要创造一个能认出我的人工智能!

桃子:我也要!我要创造一个有艺术气息、能写诗的人工智能!

小核桃:好啊,不过别着急,在真正创造人工智能之前,我们必须先做一些准备工作。计算机的智能来自人类的指令,因此我们必须学会如何给计算机下达命令。

什么是编程语言

为什么冷冰冰的机器能够按照人类的想法工作,甚至变成聪明的人工智能?相信读过前三册书的同学心里一定已经有了答案。不是因为机器聪明,而是因为人类把每一步要做什么都写成一条条指令,“告诉”了计算机。计算机只要根据指令按部就班地去执行、去计算,就可以表现得“机智过人”。对于这些告诉计算机该怎么做的指令,我们称之为计算机程序,即通常所说的代码。计算机程序就是把计算机需要做的事一步步地精确描述出来。编写程序,或者说编程、写代码,就是在给计算机下达命令。

我们平时在计算机、手机等硬件载体上使用的各种软件、App或者聪明、强大的人工智能程序,都是通过编程实现的。也可以说,程序代码构成了人工智能软件产品的“身体”

如果给这些软件穿上机械的外衣,用软件控制各种机器,就有了扫地机器人、无人驾驶汽车等人工智能硬件产品。

总而言之,掌握编程是创造人工智能产品不可或缺的技能。

不过,计算机可不懂人类的话。想要让计算机理解人类的指令,必须使用计算机的语言,也就是程序语言

人类的语言有汉语、英语、日语、法语等,计算机的语言同样种类繁多。你可能听说过C语言、Java语言、C++语言,这些都是很热门的程序语言,如图1-1 所示。

图1-1 与人类的语言一样,计算机语言也是种类多样的

这些语言具有不同的特点,适用于不同的场合。比如,C语言和C++语言,它们的特点是性能很强。用C语言和C++语言写成的程序,运行时效率非常高。但是要把这两种语言用好可不是一件容易的事,不仅编写起来麻烦,还容易出错。Java语言虽然性能稍微弱一点,但使用起来很方便,更重要的是,Java语言写成的程序可以很方便地在计算机、手机等不同的平台之间迁移。

Python同样是一门程序语言,使用非常方便,很受欢迎。表1-1展示了一些常用的编程语言,包括很多同学听说过甚至学过的Python语言

表1-1 2021年8月流行度排名前五的编程语言

排名

编程语言

流行度

对比上月

1

C

12.57%

↑0.95%

2

Python

11.86%

↓0.91%

3

Java

10.43%

↓0.74%

4

C++

7.36%

↓0.65%

5

C#

5.14%

↑0.31%

什么是Python语言

Python的发明者是一位荷兰籍程序员,名叫吉多·范罗苏姆(Guido van Rossum)。他曾在荷兰数学和计算机科学研究学会工作。1989年12月,范罗苏姆思考一个问题:该干点什么来度过长达一周的圣诞节假期呢?他思来想去,决定开发一种新的程序语言!它就是Python。当然,想在一周之内完成这么复杂的任务,确实不太可能,假期结束后,范罗苏姆继续为此努力,并在1991年以开源形式发布了Python的最初版本(Python 0.9.0)。2021年8月,Python语言3.10版本基本上开发完成,有成千上万名优秀的程序员参与了这个项目,为它做贡献。

趣闻 什么是开源?

“开源”是“开放源代码”的简称。对于常见的大部分软件,我们只有使用权,但是并不知道内部的程序代码是如何编写的——这种软件称为闭源软件。有些程序员写好软件之后,乐于公开源代码,既能让所有人都了解软件的运行原理,也能让更多的人和他合作,一起让软件变得更好用——这种软件就是开源软件。计算机领域得以飞速发展,一个重要的因素就是有无数愿意投身开源活动的程序员。很多非常重要的软件、方法都是在开源活动中诞生的。

Python这个单词的原意是“大蟒蛇”,之所以选择这个名字,不是因为范罗苏姆希望这门新语言会像大蟒蛇一样强壮、有力,而是因为他特别喜欢看一部名为《巨蟒剧团之飞翔的马戏团》的电视剧。

Python对人工智能有什么好处

Python语言非常简洁、方便。与大名鼎鼎的C语言相比,C语言要求程序员改变人的思维去适应计算机,而Python正好相反,这门语言非常贴近于人的思维习惯。好的Python程序就像一个极其严谨的人(用英语)在说话,因此非常容易理解。简言之,使用Python语言可以让你集中精力解决问题,而不是费劲地琢磨写程序的规则。这也是为什么Python在人工智能领域这么流行——实现人工智能本来就已经很难了,当然要在写代码上省点力了。

不过,Python语言也有一些缺点,比如用Python写成的程序运行起来往往会慢一些。而人工智能通常需要进行大量计算,所以我们会希望程序运行得更快。好在Python语言还有另一个优点,它可以很方便地调用以其他语言写就的程序段。我们可以先把计算量非常大、需要快速运行的部分用性能更强的C语言等写好,然后使用Python写出总体结构,对C语言模块进行调用,这样就能既写得快,又算得快了!因为这个特点,Python被戏称为“胶水语言”,就好像用胶水把各种零件迅速、方便地粘起来,如图1-2所示。

图1-2 Python被戏称为“胶水语言”

由于Python简单好用,在人工智能领域,已经有非常多的人为Python这瓶“胶水”写了很多好用的“零件”(我们通常将其称为Python库),并遵循开源精神把它们分享出来,让更多的人一起使用。这也让Python变得更加好用了。

趣闻 Python之禅

另一位对Python语言的开发做出很大贡献的程序员蒂姆·彼得斯(Tim Peters)写了一首小诗来描述Python语言写成的程序应该是什么样的。

Python之禅

优美而不丑陋,

明了而不隐晦,

简单而不复杂,

复杂而不凌乱,

扁平而不嵌套,

稀疏而不稠密,

可读性很重要,

即使实用比纯粹更优,

特例亦不可违背原则。

错误绝不能悄悄忽略,

除非它明确需要如此。

面对不确定性,

拒绝妄加猜测。

任何问题应有一种,

且最好只有一种,

显而易见的解决方法。

除非你是荷兰人,否则这方法一开始并非如此直观。

做总比不做强,

但是冒失去做还不如不做。

很难解释的,必然是坏方法。

很好解释的,可能是好方法。

命名空间是个绝妙的主意——我们应好好利用它!

The Zen of Python

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren’t special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity,

refuse the temptation to guess.

There should be one——and preferably only one——obvious way to do it.

Although that way may not be obvious at first unless you’re Dutch.

Now is better than never.

Although never is often better than *right* now.

If the implementation is hard to explain, it’s a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea —— let’s do more of those!

Python安装

要编写Python程序,首先需要安装Python,并安装合适的开发工具。这里我们介绍两种常用方式:第一,直接安装原生Python,并利用Python自带的IDLE开发工具进行编程;第二,使用集成开发环境Thonny

Python软件的安装与操作系统有关,在使用时,部分情况也会根据操作系统有所不同。在本书中,我们主要以Windows 10系统为例进行介绍,也会提及macOS或其他系统。

直接下载安装Python

安装Python最简单的方法是直接从官网进行下载。打开Python官方网站,将鼠标指针移动到“Downloads”上,这时界面上会自动显示最新稳定版Python的下载按钮,并根据你的计算机安装的是Windows系统还是macOS系统自动匹配。在编写本书时,适合Windows 10系统的Python最新稳定版本是3.9.6。单击“Python 3.9.6”按钮即可下载,如图1-3中的橙色箭头所示。

图1-3 下载Python 3.9.6

如果你的计算机安装的是更早版本的Windows系统,比如Windows 7,就需要单击“Downloads”菜单的“Windows”选项(见图1-3中的蓝色箭头),打开下载版本选择页面,如图1-4所示。

图1-4 Python官网的下载版本选择页面

在版本选择页面找到“Python 3.8.10 - May 3, 2021”(未在图1-4中显示),根据自己的计算机系统是32位还是64位,在后两个选项中选择下载,32位对应橙色箭头32-bit,64位对应蓝色箭头64-bit,如图1-5所示。

图1-5 Python 3.8.10 - May 3, 2021

如果你不知道自己的计算机系统到底是多少位,那么可以在“开始”菜单中找到“计算机”,单击鼠标右键,然后在弹出的菜单中选择“属性”(见图1-6),就可以在“系统”类型条目中看到准确的信息(见图1-7)。

图1-6 Windows 7系统的“开始”菜单

图1-7 计算机属性中的“系统”类型

如果用的是Windows XP等更低版本的操作系统,那么请先升级系统,以免书中的有些内容无法实现。

下载完成后,运行Python 3.9.6安装程序。勾选下方的两个复选框,然后单击“Install Now”,如图1-8所示。如果你对计算机和Python有比较多的了解,也可以选择“Customize installation”,自行设置安装选项。

图1-8 安装Python

等待一段时间后,安装程序会提示安装成功。单击“Disable path length limit”,然后单击“Close”按钮,即可完成安装,如图1-9所示。

图1-9 安装成功

安装好Python后,你就可以用Python自带的IDLE来编写Python程序了。

在“开始”菜单中找到Python 3.9文件夹,打开IDLE,如图1-10所示,你就可以开始编写Python程序了。如果你的计算机安装的是macOS系统,你可以在启动台找到IDLE。

图1-10 在“开始”菜单中找到IDLE(Windows 10系统)

图1-11所示的这个界面称为IDLE Shell,又称为交互模式。你在这个界面中直接输入Python代码,然后就可以看到所返回的结果了。

图1-11 IDLE Shell窗口

使用Thonny编写Python

Thonny是一款面向Python语言初学者的开源集成开发环境,使用起来非常方便。请先打开Thonny官方网站,如图1-12所示。

图1-12 Thonny官方网站

在页面右上角,请根据你的计算机所安装的操作系统选择相应的选项(如Windows),就可以下载最新版的Thonny了。在写本书时,Thonny的最新版本是3.3.13。

下载完成后,运行安装程序,可能会弹出“Select Setup Install Mode”对话框,选择“Install for me only(recommended)”,如图1-13所示,就可以正式开始安装了。

图1-13 选择安装模式

按照页面提示,单击“Next”按钮,如图1-14所示。

图1-14 欢迎安装页面

在下一个页面中,选择“I accept the agreement”,然后单击“Next”按钮,如图1-15所示。

图1-15 选择接受协议

在图1-16所示的页面中,勾选“Create desktop icon”,然后单击“Next”按钮。

图1-16 选择生成桌面图标

最后,单击“Install”按钮,如图1-17所示。

图1-17 准备安装界面

查看图1-18所示的进度条,待出现图1-19所示的“Great success!”提示,单击“Finish”按钮,安装就结束了。

图1-18 查看进度条

图1-19 安装结束

如果要取消安装,请单击图1-18中的“Cancel”按钮。安装完成后,Thonny的快捷方式图标会出现在桌面上,如图1-20所示。双击图标,就可以进入Thonny编写Python程序了。

图1-20 Thonny的快捷方式图标

Thonny的界面并不复杂。除了上文提到的菜单和按钮,界面主要分为3个部分。我们现在主要关注图1-21所示的“Shell”区域:它和前面介绍的IDLE主界面作用相同,都是交互模式。你可以在这里输入代码,按“Enter”键就可以马上得到结果。

图1-21 “Shell”区域

如果你觉得“Shell”区域太小,可以将鼠标指针移动到分界线上,待其变成像图1-21中这样的上下箭头,就可以通过上下拖动箭头来改变“Shell”区域的大小了。

Thonny比IDLE更加美观,还有一些便捷功能。虽然Thonny 3.3.13版本自带的Python(3.7.9)不是最新的版本,但是这并不影响你编写本书的程序。你也可以同时安装原生Python的IDLE和Thonny,在默认情况下,它们互不影响。

照猫画虎学Python

如果你学过Python语言,就再好不过了,你完全可以跳过本节内容,直接阅读第2章。如果你没有接触过Python语言,也不用担心,因为接下来我们会简明扼要地介绍Python语言的基本用法。

不过,本书的目的不是面面俱到地介绍Python语言。我们会简单地讲述后文要用到的Python基础功能,而不会完整地讲述这门语言的方方面面。如果你想真正深入完整地学习Python语言,那么最好再选择一本专门的Python图书,或者系统学习一些Python课程。

学习绘画或书法,往往是从临摹开始的;做数学题,也总要先研究例题;学习Python或者其他编程语言,也可以从模仿开始。本书会给出一些示例代码,以供你复制到自己的计算机上,并思考为什么这样的代码会得到这样的结果。

程序是非常严谨的语言,所以如果你是第一次了解编程,输入时一定要注意,在复制代码时,输入的内容一定要和书中代码完全一样不论是字母还是符号,都要在英文状态下输入,否则程序可能会出现错误。

理解了书中给出的例子,你就可以对这些代码进行一定的修改,然后推测修改后的结果,最后运行程序,看看和你的推测是否一样。如果你能按照自己的想法修改代码,得到想要的结果,就说明你基本掌握了所用到的知识点。

由于我们的目的不是全面地学习Python,因此书中的示例代码会尽可能少地使用Python的各种特性,所以每一段代码都可以进一步改进。等你对Python有了更多的了解,再尝试优化书中的程序吧!

Python初体验——Hello world

新手程序员们编写的第一个程序通常是“在屏幕上输出Hello world”。

在Python中,要完成这个操作非常容易。在IDLE或Thonny的Shell(交互模式)中,按照程序1.1输入代码,然后按Enter键运行程序并查看效果。其中,“>>>”是已显示在Shell窗口中的,不需要输入。注意,请在英文输入法状态下输入引号。请仔细观察你输入的英文引号和中文引号,看看是不是不太一样?

注:由于不同计算机上安装的字体库可能不同,你看到的引号的样子可能会和本书上出现的有所区别,请以实际情况为准。

程序1.1 输出Hello world

>>> print("Hello world")

如果没有输入错误,那么“Shell”区域会在下一行显示:

Hello world

效果如图1-22和图1-23所示。

图1-22 IDLE交互模式的“Hello world”

图1-23 Thonny交互模式的“Hello world”

如果你看到了图1-24中的红色提示,那么说明代码编写有误。提示的意思是说pirnt这个名字没有被定义,这是由拼写错误导致的,print错拼成了pirnt

图1-24 代码拼写错误

如果你使用Thonny,就会在Thonny界面右侧的助手窗口看到更清晰的英文提示。如果觉得提示用处不大,也可以单击“×”关掉它。

在后文中,如果要在Shell(交互模式下)区域中运行程序,我们也会用>>>作为前缀来表示输入的代码,而没有前缀的就是显示的结果。也就是说,你在本书中看到的内容和你在计算机的Shell区域中看到的内容大致相同。

print()这段代码的作用是把括号中的内容显示到屏幕上。这样有特定功能的代码称为函数,括号中的内容就是函数的参数。你可能还注意到了,Hello World外面还有一对引号,但这对引号并没有显示在屏幕上。引号表示Hello World是一个字符串,就像我们写在纸上的字一样,如图1-25所示。

图1-25 函数的构成

你也可以把引号中的内容换成别的内容试试效果,比如把英文换成数字或中文,如程序1.2所示。

程序1.2 print()练习

>>> print("1+1=2")
1+1=2
>>> print(1+1)
2
>>> print("你好,世界。")
你好,世界。
>>> print(3,"Python",3+8)
3 Python 11

注意,引号一定是成对出现的,引号之间可以包含中文符号。如果想一次显示多个内容,可以用“,”(英文逗号)分隔,相应地,这些内容在显示时会被空格分隔开。

自动补全功能

无论是IDLE还是Thonny,都支持代码的自动补全/自动完成功能。只要你输入代码词汇(如print)的一部分,然后按键盘上的Tab键,Python就可以自动把单词补充完整。注意,自动补全功能针对的是代码词汇,而不是英语词汇。

对于只有一种补全方式的情况,比如当你输入pri(只能被补全成print)并按下Tab键,Python会直接把它变成print。如果有多种补全方式,比如只输入pr并按下Tab键,就会弹出候选菜单,让你选择采用哪种方式补全,如图1-26所示。你可以用鼠标选择需要的选项,不过更常用、更方便的方法是用键盘的上下键选择,然后按Tab键确认(IDLE中需要按两次Tab键确认)。自动补全功能大大提高了我们的输入效率,也减轻了我们记住那些复杂的Python代码词汇的负担,还能减少拼写错误(也许你已经有过把print错拼成pirnt的经历了)。

图1-26 IDLE Shell的自动补全功能

Python中的空格

在“Shell”区域输入代码时,如果你看到了像下面一样的错误提示,那么通常是由在代码的开头不小心输入了空格所导致的。

这里多了一个空格
   ↓
>>>  print(1)
  File "<stdin>", line 1
    print(1)
    ^
IndentationError: unexpected indent

其实Python语言中,每行开头的空格非常重要,因为它决定了程序的逻辑关系。在Shell中,我们一般不需要在开头输入空格。

用Python作为计算器

计算机最基础的功能就是计算。常见的数学运算都可以用Python语言运行,因此你完全可以把Python当成计算器来使用。程序1.3就是数学运算符在Python中的写法。

程序1.3 数学运算符示例

>>> 10 + 20                        # 加法 +
30
>>> 10 – 20                        # 减法 -
-10
>>> 10 * 20                        # 乘法 ×
200
>>> 9 / 2                          # 除法 ÷
4.5
>>> 10 % 3                         # 返回除法的余数,在编程中通常称为取模
1
>>> 2 ** 3                         # 幂(乘方),2^3
8
>>> 9 // 2                         # 向下整除,得到小于商4.5的最大整数4
4
>>> -9 // 2                        # 得到小于商-4.5的最大整数-5
-5

除了加减乘除,比较大小同样是常用的数学运算,这就要用到比较运算符。比较运算的结果不是数字,而是逻辑上的真(True)和假(False),如程序1.4所示。TrueFalse同样是一种数据,也可以储存在变量中。在后文介绍Python中的数据类型时,我们会进一步介绍Python中逻辑上的真和假。

程序1.4 比较运算符示例

>>> 2 > 1                 # 判断是否大于 ,2>1得到真
True
>>> 2 < 1                 # 判断是否大于,2<1得到假
False
>>> 3 >= 3                # 判断是否大于或等于≥,3等于3所以3>=3得到真
True
>>> 3 <= 3                # 判断是否小于或等于≤
True
>>> 3 == 3                # 判断是否相等
True
>>> 3 != 3                # 判断是否不相等,3等于3所以得到假
False
>>> 3 != 4                # 3不等于4,所以得到真
True

还有一种运算是逻辑运算,也就是真和假两种逻辑值之间的计算。在《写给青少年的人工智能 发展》一书中,我们介绍过逻辑运算“异或”。本书常用的逻辑运算有三种,分别是逻辑与(and逻辑或(or逻辑非(not

逻辑与(and)的含义类似于我们平时说话时的“且”。如果我们说“禾木是编程比赛冠军且桃子是数学比赛冠军”,那么两件事都是真的,这句话才是真的。也就是说,逻辑运算A and B,必须AB都是True,才能得到True,否则就得到False

逻辑或(or)就是日常用语中的“或”。“禾木是编程比赛冠军或桃子是数学比赛冠军”,那么不管是禾木是冠军、桃子是冠军,还是两个人都是冠军,只要两个冠军有一个是真的,这句话就是真的。也就是说,对于逻辑运算A or B,只要AB中有任意一个是True,结果就是True。只有AB都是False,结果才是False

逻辑非(not)的含义很简单,就是得到一件事是真假的相反值。对于not A,如ATrue,那么结果就是False,反之结果就是True逻辑运算符的示例如程序1.5所示。

程序1.5 逻辑运算符示例

>>> 2 > 1 and 2 < 1       # 逻辑与and,"真and假"得到假
False
>>> 2 > 1 and True
True
>>> 2 > 1 or 2 < 1        # 逻辑或or,"真or假"得到真
True
>>> x = False
>>> not x                 # 逻辑非not,"not假"得到真
True

在Python中,除了这些最基本的运算符,还有很多其他运算符,如果后面用到,我们会再进行介绍,你也可以自行查阅有关资料。

像数学运算要先算乘除、后算加减一样,Python运算符也有运算顺序,在编程中我们一般称为优先级。表1-2列出了常用运算符的优先级,从上到下,优先级依次下降,同一行优先级相同。

表1-2 常用运算符的优先级

运算符

优先级描述

**

幂 (优先级最高)

*, /, %, //

乘,除,求余数和取整除

+, -

加法,减法

<=, <, >, >=

判断大小的运算符

==, !=

判断是否相等的运算符

=

赋值运算符(后文会进行介绍)

not,and,or

逻辑运算符

另外,和数学一样,括号中的内容是最先被计算的。如果你不确定运算符会先算哪一个,那么最好的方法就是加括号。不过在Python中,起到这个作用的只有圆括号(),也就是数学中的小括号。所以如果你想表达的运算逻辑比较复杂,可能就需要括号套括号来上好几层,这种时候就免不了有些眼花。比如下面这样(结果是34359738368.0):

18//((1+2)*3/4**((1+3)*5-3))

数学中的中括号[]在Python中一般称为方括号,有其他作用,详见后文。

变量

在程序中,我们可以直接使用各种字符串、数字等数据。但是如果要对不同的数据进行很多次相同的操作,那么直接使用数据本身就显得比较烦琐。

在各种方程式中,我们常用不同的字母来代表数字,而对于具体的数值,则可以任意代入。在编程中,我们也可以采用类似的方式,即用变量来存储数据。例如,对于Hello world程序,我们也可以按照程序1.6所示的这样写。

程序1.6 使用变量

>>> a = "Hello world"
>>> print(a)
Hello world

程序1.6的效果和程序1.1是一样的。这里的a就是变量,a = "Hello world"这句代码的作用就是将字符串"Hello world"这条数据存储在a中,这个过程称为赋值,变量中存储的内容称为变量的值

首次给变量赋值,就是新建这个变量,这通常称为声明变量定义变量。定义好变量后,在后面输入时,我们也可以使用自动补全功能。

变量赋值中的“=”并不是数学中的等号(虽然它们的外观和输入方式一样),而是一个表示赋值操作的符号,称为赋值运算符,表示把“=”后边的内容存储到前面的变量中。“=”右边既可以是数字、字符串等数据,也可以是一个数学表达式等需要计算的内容,比如a = 1 + 1,那么变量a的值就是2,如图1-27所示。

图1-27 赋值语句的代码成分

你可以把变量视作一个可以装各种东西的盒子。如果你在盒子里装入苹果,放在桌子上,那么当你和别人说“帮我把桌子上的盒子拿过来”时,对方自然就会递给你这个装有苹果的盒子,而不是大费周章地把苹果拿出来,把空盒给你。可千万不要像图1-28中的禾木那样把苹果吃掉了。

图1-28 使用变量(就是使用变量的值,而不是把变量清空)

同时,你可以随时把袋子中的东西扔掉,换上别的东西,也就是给变量重新赋值。例如程序1.7中,变量b中的数据先是字符串"你好,世界!",然后变成数字2。你还可以把变量理解为一个可以贴在任何数据上的标签,然后就能用这个标签来称呼所用的数据了。

程序1.7 变量赋值

>>> b = "你好,世界!"
>>> print(b)
你好,世界!
>>> b = 1+1
>>> print(b)
2

在赋值过程中,计算机会先计算出等号右边的结果,然后将其赋值给等号左边的变量。在数学中,x=x+1是一个没有解的方程,但是在Python编程中,它是有意义的,表示把x的值+1,然后重新赋值给x,如程序1.8所示。

程序1.8 变量自增

>>> x = 1
>>> x = x + 1
>>> print(x)
2

第一行将变量x赋值为1,因此第二行等号右边的变量x为1,1+1得到结果2,将结果2重新赋值给x,最后变量x的值就变成了2。

在Python中,我们可以一次为多个变量赋值。比如,a = b = c = 1可以将变量abc都赋值为1。又如,a, b = 2, 3 就可以将变量a赋值为2,将变量b赋值为3。还可以用一个变量来为另一个变量赋值,比如当变量a的值为1时,那么b = a可以将变量b赋值为1。我们可以用a, b = b, a方便地交换两个变量的值。程序1.9展示了这几种情况。

程序1.9 变量赋值在Python中的示例

>>> a = b = c = 1                    # 使用连等号=给多个变量赋相同的值
>>> print(a,b,c)
1 1 1
>>> a, b, c = 2, 1, 3*5              # 使用逗号,给多个变量分别赋值
>>> print(a,b,c)
2 1 15
>>> c = a                            # 用一个变量给另一个变量赋值
>>> print(c)
2
>>> a, b = b, a                      # 使用逗号,交换变量a和b的赋值
>>> print(a,b)                       # 显示变量a和b的值
1 2

你可以给变量起各种各样的名字,但是要注意,只能用字母或下划线(_)开头,不能用数字开头。变量名也不能和Python中的关键词(也就是Python语言中已用过的、有特定功能的词)重复。Python中的关键词包括下面这些:

True False None if elif else and or not for in while break continue def yield return from import as assert class del global nonlocal is lambda pass raise try except with finally

除此之外,像!@#之类的特殊符号也不能用来命名变量。如果变量名不符合规则,程序就会出错无法运行。请问下面哪个变量名是错误的?

Asd  name  123age _hao 名字 __ming_zi haha!

答案是第三个和最后一个,即123agehaha!。“名字”是可以使用的变量名。在Python中,变量名可以使用汉字(但不推荐)。

除了这些必须遵守的规则,在给变量起名时,最好使用能看懂的、有意义的词。比如给储存名字的变量起名为name,给储存年龄的变量命名为age。你也可以用拼音来命名,不过命名规则最好统一。

值得注意的是,你可以把变量命名为print,比如print = 1。但是一旦这么做了,它就失去了显示功能,只是一个变量,存储了你赋值给它的1。但是,只要重启Python,就可以恢复正常。

Thonny有一个非常有用的功能:只要单击“视图”菜单,勾选“变量”,就可以打开“变量”窗口。所有已经声明的变量及其值会显示在“变量”窗口中,如图1-29所示。

图1-29 Thonny的“变量”窗口

Python中的数据类型

在前面的代码中,我们用过数字(10,2,3)和字符串("Hello World"),这些都是不同类型的数据。Python中有多种不同的数据类型,常用的有数字字符串列表元组字典等。

数字

数字类型的数据又可以细分为很多种,最常见的就是整数(如1,记作int)和浮点数(如1.0,记作float)。浮点数其实就是小数。数字可以参与各种数学运算。

还有一种特殊的数字类型,称为布尔型(Bool)。布尔型只有两个值,即TrueFalse,这两个值分别表示“真”和“假”。布尔型用于表示逻辑上的真和假,所以有时也称为逻辑型。在编程中,我们会经常用到逻辑判断。前文提到比较运算法和逻辑运算符时,就出现了布尔型数据。

我们也可以用数字1来表示真,用数字0来表示假。实际上,在“只懂”二进制的计算机看来,TrueFalse本质上就是1和0这两个数字,如果执行计算True + True,那么可以得到结果2。这也是为什么布尔型属于数字类型的数据。注意,Python是区分大小写的,所以使用布尔值时,不要误写成truefalse。结果为布尔型值的表达式称为布尔表达式,也可称为逻辑表达式。

字符串

如果说数字对应着计算,那么文字则对应着记录。在Python语言中,文字用字符串来表示,在Python中记作str。它由一对引号中的一串字符(如字、字母、符号、数字)组成,引号可以用英文单引号('),如'Hello world';也可以用英文双引号("),如"Hello world",但需要前后一致。

字符的位置在Python中称为索引值,也有人习惯称之为元素下标序号等。与我们平常习惯不同的是,索引值是从前往后从0开始计数的,也就是说,在"Hello world"这个字符串中,H位于位置0,或者说是第0个字符。字符串中的空格同样是字符串的一部分,要占一个位置,如图1-30所示。通过索引值,我们可以方便地使用字符串的某个字符,如果用string = "Hello world"将字符串存储在变量中,那么string[0]代表第一个字符H,string[-n]代表倒数第n个字符,倒着数就是从1开始计数了,比如string[-1]代表"d"。你可以试着运行print(string[0]),再看结果。但是,我们无法修改字符串中的字符,如程序1.10所示。

图1-30 字符串的构成

如果要访问字符串的某一个片段,我们可以利用索引方便地从字符串中截取一部分——这个操作称为切片。可以用string[m:n]来访问从第m个到第n-1个(注意,是从0开始数的)字符,片段中的最后一个字符,也就是说,第n个字符不会包含在内。如果把冒号前或后的数字省略,就说明是从开头访问或访问到结尾。请尝试运行程序1.10中的代码,以理解字符串的“切片”是什么意思。

程序1.10 字符串访问字符和切片在Python中的示例

>>> string = "Hello world"        # 创建字符串
>>> print(string[0])              # 显示字符串的0号(第一个)字符
H
>>> print(string[-2])             # 显示字符串的倒数第二个字符
l
>>> string[3:5]                   # 用切片访问字符串的3、4号字符
'lo'
>>> print(string[:7])             # 显示字符串的0~6号字符
Hello w
>>> print(string[4:])             # 显示字符串的4号~结尾字符
o world
>>> string[0] = 'h'               # 不能给字符串0号字符重新赋值(修改字符串)
Traceback (most recent call last):       <==程序报错无法运行
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

在上面的例子中,我们还可以看到是否使用print()函数的区别。若不使用print()函数,则显示的字符串是带有引号的,即显示的是数据本身;若使用print()函数,则显示的字符串是不带引号的,即显示的是数据的内容。

数字1和字符串"1"虽然看起来很像,但是其实完全不同。两个数字可以进行数学运算,比如1+1可以得到数字23*2可以得到数字6,但是两个字符串不能进行数学运算。

若对字符串执行字符串+字符串的操作,会得到将两个字符串连接起来的结果;若对字符串执行字符串*数字的操作,则可以把字符串重复多次后连接;若对字符串执行字符串*字符串的操作,程序就会报错,如程序1.11所示。你也可以尝试使用其他运算符。

程序1.11 数字和字符串运算在Python中的示例

>>> 1 + 1                        # 数字进行加法+运算
2
>>> '1' + '1'                    # 字符串 + 字符串,可得到连接后的字符串
'11'
>>> '12' * 3                     # 字符串 * 数字,得到重复多次的字符串
'121212'
>>> '1' * '1'                    # 字符串 * 字符串,程序报错,无法运行
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'

我们还可以通过len()函数,快速得到字符串的长度(有多少个字符),如程序1.12所示。

程序1.12 len()函数

>>> string = "Hello world"
>>> len(string)
11

列表

列表(list)可以把多个数据储存成一组。它的样子是在一个方括号[]内,用逗号分隔开多个值。这些值称为列表的元素。

在列表中,元素不仅可以是数字,还可以是字符串,甚至可以是其他列表(列表嵌套),还可以是元组、字典等数据结构,而且每个元素的数据类型可以不同,如图1-31所示。

图1-31 列表的构成

与字符串类似,列表也可以使用列表名[数字]的方式来访问其中的某一个或某几个元素。从这个角度来讲,你可以认为字符串是一种特殊的列表。字符串中的切片方式,对于列表全部可以适用。对于嵌套的列表,我们可以用连续的两个中括号进行嵌套访问。

我们也可以对列表中的元素进行重新赋值,但字符串中的字符不能改变。列表使用和赋值示例如程序1.13所示。

程序1.13 列表使用和赋值示例

>>> mylist = ['hello', 23, 3, [2, 45]]  # 创建列表
>>> mylist[0]              # 访问列表中0号元素,这是一个字符串
'hello'
>>> mylist[:2]             # 切片访问前两个(0、1号)元素,得到2个元素的列表
['hello', 23]
>>> mylist[-3:]            # 切片访问倒数3个元素,得到3个元素的列表
[23, 3, [2, 45]]
>>> mylist[3]              # 访问3号元素,这个是一个列表
[2, 45]
>>> mylist[3][1]           # 嵌套访问3号元素(列表)中的1号元素
45
>>> mylist[0] = 0          # 重新赋值0号元素
>>> mylist[1:] = [1,2,3]   # 重新赋值1号到最后的元素
>>> mylist                 # 调用改变后的列表进行查看
[0, 1, 2, 3]

像字符串(str)运算可以使用的+*运算符一样,它们和len()函数也可以用在列表上,如程序1.14所示。

程序1.14 列表运算符示例

>>> [1] + [1]                       # 列表 + 列表,得到连接后的列表
[1, 1]
>>> [1,2] * 3                       # 列表 * 数字,得到多次重复的列表
[1,2,1,2,1,2]
>>> len([0,4,5])                    # len(列表),得到列表长度(元素个数)
3

还有一些简便的方法可以用于操作列表,如程序1.15所示。

程序1.15 操作列表的其他方法

>>> x = [1, 2, 3]
>>> x.append(4)        # 列表.append(元素),将元素增加到列表末尾
>>> x
[1, 2, 3, 4]
>>> x.extend([5,6])    # 列表.extend(列表),将两个列表拼接,类似列表 + 列表
>>> x
[1, 2, 3, 4, 5, 6]

元组

元组是和列表非常相似的一种数据类型,在Python中记作tuple它用一对圆括号和括号中用逗号分隔的元素来表示。元组的使用方法和列表基本一样,同样使用方括号和索引来访问元素,但是它的元素不能像列表一样修改,否则程序会出错无法运行。使用元组的示例如程序1.16所示。

程序1.16 使用元组的示例

>>> mytuple=(1,2,3)                      # 定义元组mytuple
>>> mytuple[1]                           # 访问元组中1号元素
2
>>> mytuple[0]=5                         # 修改元组中元素会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

元组和列表如此相像,看似有点画蛇添足,而且元素不能改变,似乎也是它的缺点。不过,正是这种不能被改变的特性,可以保证它在使用中不会被意外修改。

字典

有时我们遇到不认识的字,会查字典。查字典时,只要有了目标关键字,就可以在字典中找到相应的详细信息。Python中的字典就是这样的数据类型。

字典由多个键值对组成,键(key)就像索引值,可以由我们自己指定;每个键都有对应值(value)。

字典的每个键值对用英文冒号(:)分割,每个键值对之间用英文逗号(,)分割,整个字典包括在英文花括号{}中,如图1-32所示。

值可以是任何数据,但键只能是字符串、数字、元组这样的不可变数据类型,而列表、字典不能作为字典的键。使用方括号和键可以访问字典中的某个值。使用字典的示例如程序1.17所示。

图1-32 字典的构成

程序1.17 使用字典的示例

>>> d = {'A':100, 2:'B', (1,2):[2,3]}        # 定义字典d
>>> d['A']                      # 访问字典中键'A'对应的值(键可以是字符串)
100
>>> d[2]                        # 访问字典中键2对应的值(键可以是数字)
'B'
>>> d[(1,2)]                    # 访问字典中键(1,2)对应的值(键可以是元组)
[2, 3]
>>> d['A':2]                    # 对字典切片会报错
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
    TypeError: unhashable type: 'slice'

不过,虽然字典中的元素看起来是按照顺序排列的,但是在计算机中存储时,它没有顺序,所以不能使用列表、元组或者字符串中的切片操作(如d['A':2]),即使我们把键设置为0、1、2、3这样,也不可以。

保存编写的程序

我们已经用Python的交互模式(Shell)写了很多代码,但是使用交互模式,只能像一个高级计算器一样,每次输入一句,而且每次启动Python想重新再执行之前的程序时,只能重新输入,也不方便编辑。

有没有其他可以输入和编辑代码的方式呢?答案是肯定的。编辑器模式就可以自由输入Python代码并进行编辑,让代码组合起来变成能实现完整功能的程序,之后可以反复执行。

IDLE的编辑器模式

在IDLE中,依次单击菜单栏中的“File”→“New File”,就可以打开IDLE编辑器窗口了,如图1-33所示。

图1-33 打开IDLE编辑器窗口

你可以尝试在编辑器中写下我们在“Shell”领域中用过的代码,如程序1.18所示。

程序1.18 尝试使用编辑器

print("Hello world")
1+1

编辑器窗口同样可以实现自动补全功能。为了更方便地定位代码,我们可以让编辑器在每行代码前面显示行号。如图1-34所示,依次单击菜单栏中的“Options”,→“Show Line Numbers”,就可以显示图1-35左侧的行号了。注意,不要把行号当成代码的内容

图1-34 显示行号的命令

图1-35 显示了行号的代码

然后,依次单击菜单栏中的“File”→“Save”,就可以将写好的程序保存成扩展名为.py的程序文件,如图1-36所示。Python的程序文件也可以称为Python脚本文

图1-36 保存程序文件

最后,依次单击菜单栏中的“Run”→“Run Module”,或者直接按键盘上的“F5”键,就可以运行程序了,如图1-37所示。

图1-37 运行程序

注:有些键盘上有“Fn”键(如大多数笔记本电脑的键盘),你可能需要同时按“Fn”和“F5”两个键。

运行程序时,IDLE会自动跳转回Shell窗口,并在这里输出程序的运行结果,如图1-38所示。

图1-38 显示在Shell窗口的程序运行结果

通过打开文件运行程序,和直接在Shell窗口运行代码有些不同。程序1.18中第二行代码1+1,没有被输出显示(但是不影响其执行)。也就是说,只有通过print()等相关功能的函数,我们才能看到程序文件中的运行结果。

程序运行结束后,Shell窗口不会自动关闭,程序运行时产生的各种变量也会保留最终状态。你可以在这里通过交互模式继续操作这些变量。

运行程序t_shell.py后,我们可以继续在Shell窗口中操作变量a,如图1-39所示。

图1-39 程序运行完毕后可以在Shell窗口继续操作变量

但如果再次运行一个程序文件,那么运行之前的数据都会被清除。

Thonny的编辑器模式

Thonny的编辑器位于“Shell”区域的上方,如图1-40所示。

图1-40 Thonny的编辑器

Thonny编辑器同样可以实现自动补全。在编辑器中写代码时,行号会自动出现在代码的左侧。

Thonny编辑器上方有几个按钮,分别是“新文件”按钮(用于新建程序文件)、“打开”按钮、“保存”按钮、“运行”按钮(用于运行程序文件)、“调试”按钮以及“停止并重启”按钮(用于停止运行并重启Python内核程序),如图1-41所示。将鼠标指针移动到图标上停留一会儿,就会自动显示按钮的名字。

图1-41 Thonny中的相关按钮

单击“运行”按钮,就可以执行写好并保存的程序文件。程序运行结束后,变量同样会被保存,这样你就可以在“Shell”区域对其进行操作。再次运行程序文件前,所有之前的数据会被清除。单击“停止并重启”按钮,也可以清除数据。

单击“调试”按钮,即可调试当前脚本。调试又称为Debug,也是编写程序时的一项重要内容,可以帮你找出程序中的错误。双击某一行的行号位置,你会看到行号后面显示一个红点,如图1-42所示,这表示在此行设置了断点。

图1-42 在Thonny中设置断点

如果程序使用调试模式运行,就会在断点位置暂停(执行这一行之前)。暂停后,你可以观察变量窗口的数据,或者在“Shell”区域执行相关命令,以观察运行时的数据是否符合自己的预期,如图1-43所示。

图1-43 Thonny调试

囿于篇幅,我们在这里不详细介绍其他内容。你可以参考其他专门讲解Python编程的图书。

IDLE同样支持调试功能。你可以通过在编辑器中的代码上单击鼠标右键,然后在弹出的菜单中选择“Set Breakpoint”来设置断点(见图1-44),然后在“Shell”区域中单击菜单栏中的“Debug”→“Debugger”,打开调试器,如图1-45 所示。

图1-44 设置断点

图1-45 打开调试器

Python语言的逻辑结构

写作文时,语文老师经常会说要注意文章的逻辑结构,把文章的观点表达得更清晰。编写程序更是如此。

顺序结构

我们在“Shell”区域中编写的代码,都是执行完一句再执行下一句,如图1-46所示。这样依次按顺序执行的结构称为顺序结构。顺序结构是最常见、最基本的结构。

图1-46 顺序结构

但是,对于现实世界中的很多问题,我们通常无法按照顺序的方法实现,而是需要经常做出判断和选择,这时就要用到分支结构(选择结构)

分支结构

密码是保护秘密的重要工具。无论是登录自己的QQ号,还是买东西时用手机付款,都需要密码。如果要设计一段程序来检测密码是否正确,应该怎么做呢?首先我们需要向程序输入密码,然后程序会对我们输入的密码与程序中储存的密码加以比较和判断,如果相同,那么说明密码正确,否则就提示密码错误。

如果……那么……否则……,这就是一种分支结构。在Python中,要构造分支结构,可以使用ifelifelse关键字。

分支结构的格式如下,if后面跟随的是布尔表达式或布尔值,例如比较运算符、逻辑运算符构成的表达式。如果布尔表达式的结果为真(True),那么执行代码块1的内容,执行完后跳过代码块2部分,结束这部分程序;如果布尔表达式的结果为假(False),那么跳过代码块1,执行代码块2的内容,如图1-47所示。

if布尔表达式:
    代码块1
else:
    代码块2

图1-47 选择结构

代码块1代码块2的前面都有空格,或者说它们进行了缩进Python中使用缩进的方式来表示代码的层次结构,缩进相同(空格一样多)就表示它们处在同一个层次。

换句话说,如果几行代码是连续的,而且保持了相同的缩进,那么它们就属于同一个代码块,相当于一个执行的整体。例如if条件成立的情况下,如果需要执行多条语句,那么只要连续输入几行代码,并保持相同的缩进(空格一样多)就可以了。缩进可以使用任意数量的空格,但通常使用4个空格

程序1.19的例子展示了如何构造一个分支结构。input()的作用是让程序接收使用者输入的内容,将括号中的内容显示在屏幕上,作为提示。使用者输入内容后,按Enter键予以确认,输入的内容就会变成字符串,作为input()的结果赋值给变量password。注意,#后面的内容起到解释这一行代码的作用,不需要作为代码来输入。冒号(:)要以英文状态输入。

程序1.19 使用分支结构来判断密码

1    password = input("请输入密码:")       # 向程序输入密码
2    correct_pass = "123456"              # 正确的密码是123456
3    if password == correct_pass:         # 比较输入的密码和正确的密码
4        print("密码正确")                 # 比较结果为True则显示密码正确
5        print("欢迎进入")                 # 相同的缩进说明属于同一个代码块
6    else:                                # 否则
7        print("密码错误")                 # 显示密码错误

有时我们需要做出多次判断,那么可以在中间再加一个或多个elif,如下所示:

if布尔表达式1:
    代码块1
elif布尔表达式2:
    代码块2
else:
    代码块3

如果布尔表达式1为False,就会再用同样的方式判断布尔表达式2,运行程序。例如,程序1.20所示的代码会将分数转换成评价,即90分及以上是优秀,60~89分是良好,60分以下是不合格。由于input()的结果是字符串,因此要与分数数字比较大小,必须先用int()将其转换为数字。

程序1.20 使用elif的示例

1    score = input("请输入分数:")             # 输入分数
2    score = int(score)                      # 将分数字符串转换为数字
3    if score >= 90:
4        print("优秀")
5    elif 60 <= score < 90:
6        print("良好")
7    else:
8        print("不合格")

和C语言等编程语言不同,Python中可以使用像60 <= score < 90这样连续的比较,这条语句相当于60 <= score and score < 90,和数学表达式相差无几。

我们还可以嵌套使用if结构,也就是把各个代码块换成另一层if结构,就像下面这样。嵌套部分的代码块(代码块1代码块2)前面需要额外空4个空格,也就是有8个空格。

if布尔表达式1:
    if布尔表达式2:
        代码块1
    else:
        代码块2
elif布尔表达式3:
    代码块3
else:
    代码块4

循环结构

在编写程序时,我们有时需要将一段代码反复执行很多次。比如,如果想用*来组成一个如下所示的3×3方阵,那么可能会写下程序1.21这样的代码。

***
***
***

程序1.21 显示星号方阵的直接方法

1    print('*'*3)           # '*'*3就表示字符串'***',参见前文字符串部分
2    print('*'*3)
3    print('*'*3)

但是如果要重复1000次,就很难这样写了。这时可以选择使用循环结构

Python中的循环结构有两种形式。第一种形式是while循环。

while布尔表达式:
    循环体代码块

效果是当布尔表达式的结果为True时,反复执行下面的代码块,否则就结束循环,如图1-48所示。

图1-48 循环结构

例如,前文显示*的代码可以改写为程序1.22。

程序1.22 使用while循环显示星号方阵

1    i = 0
2    while i <3 :
3        print('*'*3)
4        i = i + 1

循环变量i从0开始,当i<3时,就会反复执行循环体代码块,也就是输出***,并将循环变量i增加1。执行3次后,循环变量i就变成了3,不再满足i<3的条件,循环结束。

循环变量会随着循环的进行而改变,所以如果适当改动代码(见程序1.23),就可以输出如下由*组成的三角形。

*
**
***

程序1.23 使用while循环显示星号三角

1    i = 1
2    while i <4 :
3        print('*'*i)
4        i = i + 1

while循环一般用在循环次数不确定的场合。比如输入密码时,如果密码不正确,就反复输入,密码正确就结束,如程序1.24所示。

程序1.24 使用while循环反复询问密码,直到正确

1    correct_pwd = 'hetao'           # 正确的密码
2    pwd = input('请输入密码:')       # 用户输入密码
3    while pwd != correct_pwd:       # 比较密码是否正确
4        pwd = input('请输入密码:')   # 如果密码错误,则进入循环,重复输入密码
5    print('密码正确')                # 如果密码正确,则退出循环,显示"密码正确"

第二种循环形式是for循环

for变量in可迭代对象:
    循环体代码块

for循环会将可迭代对象中的所有内容依次赋给变量,并执行循环体代码。像字符串、列表、元组、字典这样含有多个元素、可以一一计数的对象,都是常见的可迭代对象。

for循环常用来进行遍历或枚举,比如列出一组中所有同学的名字,可以写成程序1.25。

程序1.25 列出一组中所有同学的名字

1    Group_1 = ['禾木','桃子','乌拉乎','小核桃']
2    for name in Group_1:
3        print(name)

像前文显示的*方阵,是执行次数确定的循环,属于for循环的适用场景。你可以使用for循环进行3次循环,如程序1.26所示。

程序1.26 使用for进行3次循环

1    seq = [0,1,2]
2    for i in seq:
3        print('*'*3)

不过,我们通常会采用另一种更方便的写法,那就是使用range()函数,如程序1.27所示。

程序1.27 使用range()函数

1    for i in range(3):
2        print('*'*3)

range(3)表示产生一个从0开始、小于3的序列(也就是0,1,2)。这个序列是另一种可迭代对象,for循环最终执行3次。我们可以向range()函数输入更多参数,如range(1,3)表示产生一个从1开始、小于3的序列(也就是1,2);range(1,6,2)表示产生一个从1开始,小于6,而且间隔是2的序列(也就是1,3,5)。range()函数产生的序列,都不包括我们输入的末端数字,这个特点和列表、字符串切片一样。

无论是while循环还是for循环,都可以利用break语句强行中断循环,继续执行循环后的语句。程序1.28中两个循环都是将循环变量从0增加到99,但是由于break的存在,它们都会在循环变量为3的时候停止循环。

程序1.28 break语句可以终止循环

1    i = 0
2    while i <100:
3        i = i + 1
4        if i==3:             # 当i为3时
5            break            # 强行中断循环
6    print(i)
7
8    for j in range(100):
9        if j==3:             # 当j为3时
10           break            # 强行中断循环
11   print(j)

如果将break改为continue,那么循环会跳过本次循环中剩下的代码,直接进入下一次循环代码,如程序1.29所示。

程序1.29 continue语句可以跳过本次循环后续内容

1    for j in range(5):
2        if j==3:              # 当j为3时
3            continue          # 跳过后面内容
4        print(j)

上面的循环会跳过3,显示结果如下:

0
1
2
4

函数

循环可以将同一段代码连续反复执行。但有时我们需要将一段代码灵活地插入程序中的不同位置,就像在数学题中使用数学公式一样,这时循环就显得非常死板,无法满足我们的需求。这时我们可以使用函数。函数就是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。

将一段具有特定功能的代码定义为函数,然后只要使用函数的名字,并输入合适的参数,就可以方便地使用它了。参数就是输入给函数、供函数使用的变量等对象print()input(),这些都是Python中自带的常用函数。

我们也可以把自己写的代码变成函数。函数的定义非常方便,如下所示:

def函数名字(参数):
    代码块
    return结果

定义好函数后,我们就可以用函数名字(参数)的方式调用函数。在程序中,函数定义代码的位置必须在调用函数的前面。

圆的面积公式是S=π×r2,我们可以将这个公式定义为函数(π取值3.14),并计算半径为3和8的圆的面积,如程序1.30所示。

程序1.30 使用函数计算圆面积

1    def circle_area(r):
2        S = 3.14 * r**2
3        return S
4    print(circle_area(3))
5    x = 8
6    y = circle_area(x)
7    print(y)

要注意的是,除了少数特殊情况,定义函数使用的各个变量都只在函数内部有效,与函数外的变量互不影响。函数执行结束后,所有函数中的变量会被清除,只输出结果。也就是说,函数结束后,不会再有一个变量S存储着计算好的圆面积,你需要立即直接使用或将输出结果赋给别的变量。

同时,使用函数时,作为参数传入函数的变量名与定义函数时使用的变量名也没有关系,既可以相同,也可以不同。

函数也可以没有参数,甚至没有输出结果。比如程序1.31中的函数,不需要参数,也没有输出,每次调用就在屏幕上显示“你好世界”和“Hello world”。

程序1.31 没有输入输出的函数

1    def hello():
2        print('你好世界')
3        print('Hello world')
4    hello()

注释

在前面的代码中,你一定注意到有很多“#”。这个符号用于表示注释,是给人看、帮助人理解程序用的,计算机不会执行其后的内容

注释还有一种写法:使用3个引号开头,再用3个引号结尾,单引号和双引号都可以使用,但是一次只能使用一种。这种方式可以进行多行注释,如程序1.32所示。

程序1.32 注释

1    # 这里的内容是注释
2    ''' 使用3个单引号开始注释
3        可以进行多行注释
4        再使用3个单引号结束注释'''
5    """使用3个双引号开始注释
6        可以进行多行注释
7        再使用3个双引号结束注释内容"""

使用Python库

在Python中,有大量方便的函数可供使用,实现包括屏幕显示、操作文件、数学运算、计算时间、网络数据处理、图形界面等功能。为了方便管理和使用,开发人员把它们分成了很多组,也就是Python库。Python语言自带的库又称为标准库。在Python语言中,库一般是以的形式组织的,每个包中有多个模块,模块中有不同的函数。如果觉得比较复杂,你暂时可以把库、包和模块看成同样的东西。

想要使用功能丰富的Python库函数,必须先导入相关的Python

比如,求绝对值是一种常见的数学运算,Python标准库math中的fabs()函数就可以求出绝对值。使用fabs()要先导入math库。程序1.33是使用绝对值函数fabs()最常见的做法。

程序1.33 使用math库中的绝对值函数fabs()

1    import math
2    x = math.fabs(-3)
3    print(x)

使用fabs()时,还需要在前面加上math.,用于说明fabs()函数在math库中。

有时库的名字很长,使用不方便,你还可以给导入的库另起一个名字,也就是别名。程序1.34中的代码在导入math库时将它改名为mt。改名时要特别注意,不要引起混淆。

程序1.34 给math库起别名

1    import math as mt
2    x = mt.fabs(-3)
3    print(x)

如果只使用少数几个函数,也可以只导入函数,而不导入整个库。下面的代码只导入了fabs()函数,没有导入math库中的其他函数。在这种情况下,你可以直接使用被导入的函数,不需要带上库名前缀,如程序1.35所示。

程序1.35 直接导入库中函数

1    from math import fabs
2    x = fabs(-3)
3    print(x)

使用as起别名对于函数来说同样有效,如程序1.36所示。

程序1.36 函数别名

1    from math import fabs as jueduizhi
2    x = jueduizhi(-3)
3    print(x)

第三方库

Python的标准库虽然功能强大,但也不是万能的。为了弥补标准库的不足,很多程序员也会把他们编写的各种功能、函数写成库,并共享出来,这就是第三方库

使用第三方库的代码和使用标准库没有什么不同。不过,第三方库不是Python语言自带的,所以使用前要先进行安装。

对于不同的Python开发工具和操作系统,安装第三方库的方式有一些区别。下面我们介绍如何对原生Python的IDLE和Thonny安装第三方库。注意,如果你同时安装了这两种开发工具,用两种方式安装的第三方库不能给对方使用,必须各自安装。

使用Python自带的IDLE工具编写程序

如果使用IDLE编写Python,那么最方便的当属利用pip命令进行安装。pip是Python自带的一个库管理工具,它可以自动从网络上下载你需要的Python库进行安装。大多数Python库都可以利用pip安装。

pip需要在命令行模式下输入命令来使用,这听起来好像有点陌生,但其实一点都不难。要使用pip,首先要连接网络

Windows系统下,同时按住键盘上的Windows图标键R键(后面记为Windows + R),即可打开运行窗口。在运行窗口输入“cmd”,然后单击“确定”按钮,如图1-49所示。

这样就可以打开命令提示符窗口(也称为命令行窗口),如图1-50所示。

图1-49 运行窗口

图1-50 命令提示符窗口

在命令提示符窗口中输入命令,再按下Enter键,就可以安装Python库了。注意,pip必须在联网的情况下使用

pip install库名

例如,我们会使用requests库,就需要在命令提示符窗口输入以下命令:

pip install requests

然后,按Enter键,如图1-51所示。

图1-51 输入pip命令

安装成功后,一般会提示Successfully installed+库名,如图1-52所示。

图1-52 安装成功

另外,如果你看到了和图1-52中内容类似的黄色提示,说明pip版本不是最新版,可以通过如下命令进行升级:

pip install --upgrade pip

如果要卸载一个安装好的Python第三方库,只需要把安装时的install改成uninstall就可以了。

Windows 10系统下,你也可以通过依次选择“开始”菜单 →“Windows系统”→“命令提示符”来打开命令提示符窗口,如图1-53所示。

图1-53 Windows 10“开始”菜单中的“命令提示符”

如果你使用的是macOS系统,那么可以同时按下Command键+空格键,打开“聚焦搜索”,然后输入“terminal”,打开“终端”,再输入相应的pip命令。你也可以通过“启动台”→“其他”→“终端”打开终端窗口。

使用Thonny编写Python

如果你使用的是Thonny,那么必须使用Thonny的包管理功能来安装第三方库。打开Thonny,在联网的情况下,依次选择菜单栏中的“工具”→“管理包”,如图1-54所示。

图1-54 Thonny的包管理功能

输入想要安装的包“requests”,然后单击“Search on PyPI”按钮,得到图1-55所示的结果。在得到的结果中,选择想要安装的包,也就是第一个选项。

图1-55 搜索requests的结果

选中后单击“安装”按钮,如图1-56所示,如果没有提示失败,就说明安装成功了。安装成功后,“安装”会变成“升级”和“卸载”。

图1-56 准备安装requests包

趣闻

为什么编程语言都是英语,有没有中文编程语言?

如果你对编程语言有些了解,也许会好奇为什么编程语言都是英语。Python语言中的ifwhileprint,都是用英文字母、英文单词写就的。这对于很多英语不熟练的同学确实是不太友好,那么能不能用汉语来写程序呢?

首先我们要纠正一个说法,虽然编程语言借用了英文字母,但是它并不是英语,而是独立的编程语言,符合编程语言的语法规则。其实在很多程序语言中,我们也确实可以使用汉字。但同样地,我们不能说这是在用中文写程序。

在Python中,你可以使用汉字作为变量名或者函数名。比如下面的程序是可以运行的:

>>> 核桃 = 1
>>> 编程 = 2
>>> print(核桃 + 编程)
3

不过,在真正编写程序时,一般不建议使用中文变量名。Python语言中的各种符号必须使用英文符号,如果写程序时夹杂了中文变量名,那么很容易出现忘记切换输入法,不小心输入中文符号的情况,导致程序出错。

不过,完全使用汉字和中文符号的编程语言也是存在的,比如有一门叫作“易语言”的编程语言就是这样的。不过,这门语言存在一些问题,所以使用它的专业程序员并不多。

除了“易语言”,2019年还有人发明了一门用文言文编程的程序语言“文言编程”,也很有意思。比如,下面这段程序的效果是输出3遍“問天地好在。”

吾有一數。曰三。名之曰「甲」。
為是「甲」遍。
吾有一言。曰「「問天地好在。」」。書之。
云云。

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e59088”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

相关图书

信息学奥赛CSP-S初赛通关手册10年真题+10套模拟  精练精讲
信息学奥赛CSP-S初赛通关手册10年真题+10套模拟 精练精讲
中学生C++创意编程
中学生C++创意编程
青少年编程魔法课堂 Python图形化创意编程
青少年编程魔法课堂 Python图形化创意编程
青少年编程魔法课堂 C++图形化创意编程
青少年编程魔法课堂 C++图形化创意编程
青少年Python趣味编程
青少年Python趣味编程
趣味掌控板编程
趣味掌控板编程

相关文章

相关课程