Python基础

前言

Python介绍与开发准备

Python简介

回顾Scratch:Scratch是一种图形化编程语言,对于初学编程的人来说特别友好,能够用拖拽代码的形式快速的学习编程的基本概念,如果你还没有接触过编程,建议先简单学习下Scratch,对于后续的Python学习会很有帮助。

Python简介:Python是目前主流的编程语言之一了,一方面是由于它的语法较为简单、上手比较容易;另一方面也是因为它的开放性,有很多有趣有用的第三方模块可以供我们使用,尤其是最近火热的人工智能更是Python擅长的领域。对于青少年来说,选择Python作为代码编程的选择是非常适合的,不仅能够体验编程的乐趣,更能够为将来的C++学习奠定一个基础。

Python安装

要编写Python程序,首先要往电脑中安装Python环境,不同的电脑系统适用的Python版本是不一样的,下面我们来讲解具体的安装步骤。

  1. 搜索Python,找到官方网站:www.python.org;
  2. 默认点击下载即可,但是这里有个提示如果你是windows7的话,就得安装3.9之前的版本了,也就是说最新版本的Python已经不支持windows7操作系统了;
  3. 下载好之后双击安装,安装的时候注意勾选Add python to PATH,最好点击自定义安装然后选择all users.

交互模式

安装完成之后我们可以通过程序菜单找到Python,点击图标即可进入到Python的交互环境,在这里可以进行简单的计算,比如1+1回车就可以看到答案了,当然也可以进行基础的编程,比如建立一个变量a=1回车,再建立一个变量b=2回车,然后计算a+b回车,不理解这部分内容的话也不要紧,后面紧跟着我们就会开始讲解变量的知识了。 另外,还有其他快捷的方式进入Python交互模式,按住windows键和R键打开运行框,然后直接输入python就可以了;还可以先输入cmd打开命令行,然后输入python,在这里还可以输入exit()回车后退出python交互模式回到普通的命令行模式。

IDLE

如果要写比较复杂的程序并且想要把程序保存下来的话,用交互模式就不行了,这时候我们可以选择Python自带的IDLE,从程序菜单中找到IDLE打开,默认显示的是交互模式,但是也可以从左上角的File这里选择New File,也就是新创建一个文件,在这里编写的代码就可以进一步保存起来了,保存好之后可以选择Run->Run Module执行这个文件里面的程序。 但是IDLE只有最基本的编辑功能,没有像自动提示、颜色高亮等高级功能,为了更方便的编写Python程序,我们还得再学习一个工具VSCode.

VSCode

VSCode是一个独立的软件,可以编写各类程序,我们可以简单配置后用于编写Python程序,那么如何安装呢?

  1. 搜索VSCode,找到VSCode官方网站:https://code.visualstudio.com/;
  2. 下载最新版的VSCode即可,这里默认下载的user版本,建议点击这里进去之后下载对应的system版本;
  3. 下载好之后双击安装,安装完成之后我们在扩展中安装Python插件,之后打开自己专门写Python程序的文件夹,注意这里的路径最好不要有中文以免不必要的麻烦,
  4. 搞定之后新建一个test.py,输入print("Hello World"),运行程序能看到Hello World就证明我们配置好了。 为了让VSCode更好用,我们做几个简单的配置:
  5. 鼠标滚轮控制字体大小;
  6. 自动保存;
  7. 更换主题;

变量和类型

我们通过一个实际的案例来学习编程里很重要的变量的概念,案例的名字叫狗龄计算器,具体功能为:输入一只狗的实际年龄,这个计算器会告诉你对应的人类年龄,也就是相当于人的多少岁。要完成这个计算,只需要把狗的年龄乘以7。就这么简单,开始吧! 我们把这个实际的项目案例分成了几个步骤来完成,这也是编程的基本思路:把大的任务拆解成一个个小的任务,然后分别来编程解决这些小任务,最终我们就完成了大的任务。对于狗龄计算器来说,我们拆分成如下几个任务:

  1. 向用户询问狗狗的名字;
  2. 向用户询问狗狗的年龄;
  3. 将狗狗的年龄乘以7得到相对应的人类年龄;
  4. 把结果友好的输出给用户:你的狗狗xx对应到人类年龄xx岁了; 接下来我们依次来实现每一个小任务,并讲解对应的知识点。

向用户询问狗狗的名字

为了实现这个任务,我们需要提示用户提供狗狗的名字,然后记住这个名字,以便在第4步中使用。为此我们要学习两个知识点:

  1. 如何把我们通过键盘输入的内容传递给python;
  2. 如何让python把我们输入的内容保存起来;
input函数如何工作

在python中有一个向用户请求输入的功能,叫input函数。(函数的具体定义在后面的章节中会讲解,可以简单地把它想成是调用了python提供的一个功能)。下面来看具体用法:

input("请问你的狗狗叫什么名字?")`

其中,input为函数的名字,代表输入的意思;调用input函数(或者说使用input功能)需要在后面跟上一对括号;括号里面的是提示用户的文字,需要放在两个引号之间。 括号和引号一定要注意使用英文模式的输入法输入,python代码中最常见的错误就是把括号引号等写成了中文,你可以实际输入一下中英文的括号和逗号,感受他们的区别 如果运行这段程序的话,python就会提示用户去输入一些内容,按下回车键意味着输入结束。那输入的名字去哪里了呢?这就引出了我们的第二个知识点。

使用变量保存值

变量是每种编程语言必不可少的功能,它的主要功能就是帮助我们存储一些内容以便后面使用,它的主要用法如下:

dog_name = "大宝"`

其中,左边的dog_name是变量的名字,中间的等号在编程中被称作赋值符号,右边的“大宝”是具体的内容。这一行代码的意思就是把变量dog_name赋值为大宝,也可以说把大宝这个名字存储到dog_name这个变量中。 关于变量的名字:名字可以随意起,但是有一些基本的规则:必须是连在一起的,不能有特殊符号,不能数字开头,我们这里通过下划线把两个单词组合在一起作为我们变量的名字,当然也可以是dogname,dogName等形式

将用户的输入赋值给一个变量

接下来我们将上面的两个知识点组合起来:首先让用户输入一个狗狗名字,然后把名字存到一个变量中。代码如下:

dog_name = input("请问你的狗狗叫什么名字?")`

这样我们就完成第一个小任务了,接下来进入第二个小任务。

向用户询问狗狗的年龄

学会了向用户询问狗狗的名字之后,怎么实现向用户询问狗狗的年龄是不是就比较简单了呢?代码如下:

dog_age = input("请问你的狗狗几岁啦?")`

现在我们已经得到狗狗的名字和年龄了,以后怎么使用它们呢,这就要用到print函数了。

print函数

print函数,也就是打印输出功能可以说是python编程中最常用的功能了,通过他我们可以把变量中的内容输出显示出来。代码如下:

print(dog_name)
print(dog_age)
python文件

现在我们的代码已经有好几行了,在IDLE的交互模式下只能一行一行的运行,怎么把它们组合在一起编程一个真正的程序呢,我们在IDLE中新建文件就可以了,当然你也可以选择在VSCode中新建文件。

变量之所以叫变量

变量之所以被叫做变量是因为变量中存储的内容是可以变化的,例如如下代码:

a = 1
a = 2

我们首先新建了一个变量a,然后把a赋值为了1,这时候变量a里面存的内容是1;接下来我们又把a赋值为了2,这时候变量a里面存的内容就变成了2,我们也可以说变量a被改变了。

运算符与表达式

改变变量的方法不只是直接把内容写在等号右边,我们也可以使用一些比较复杂的表达式,表达式跟数学表达式很像,由+,-,*,/等运算符组成。比如:

a = 1 + 1

在这个例子里面,python会首先计算等号右边的表达式:1+1,然后把计算结果2赋值给等号左边的变量a,相当于如下代码:

a = 2

也支持小数、乘法,如下:

b = 10*3.14159

也支持小括号

n = (98+97+58)/3

也支持在表达式中使用变量

a = 98
b = 97
c = 58
n = (a+b+c)/3

操作符之间的优先级也是支持的

n = 3 + 4 * 5

答案是35 还是 23 ? 常用操作符优先级从高到低排序如下:

操作符说明
**两个星号表示求指数,2**3就是2的3次方
* / %%是取模操作符,取模可以求出除法的余数,例如7%3为1
+ -
另外,表达式不仅限于数学运算,两个字符用加号操作的话就是连接的效果
a = 'Hello"
b = "大宝"
n = a + " " + b  # 右边表达式计算的结果为"Hello 大宝"并且赋值给n

掌握变量的知识之后,我们回到案例项目,继续我们的第三个小任务。

计算狗狗的年龄

在这一步中我们只需要把狗狗的年龄乘以7就可以得到对应的人类年龄,看起来很简单,代码如下:

dog_age = 12
human_age = dog_age*7
print(human_age)

运行程序会发现我们得到了84,很简单的就完成了任务。但是别忘了我们是需要让用户输入狗狗姓名和年龄的,因此完整的代码如下:

dog_name = input("请问你的狗狗叫什么名字? ")
dog_age = input("请问你的狗狗几岁了? ")
human_age = dog_age * 7
print(human_age)

运行程序时输入年龄12,会发现我们得到的结果居然是12121212121212,这显然是不对的! 问题出在哪里呢?你可以在IDLE中试试如下代码: 图片 仔细观察会发现,将数字用引号括起来之后的乘法跟没有引号是完全不同的,这里有一个新的概念:字符串,用引号括起来的的内容我们称之为字符串,跟数字是不同的数据类型,关于数据类型,我们马上讲解。 回到我们的问题上,我们会发现input函数其实返回的是一个字符串,而我们需要的是一个数字,带着这个问题进入数据类型的章节。

数据类型

python中每一个数据都有一个类型,不同的类型有不同特性,比如在上面的乘法中,不同类型的数据用同样的乘法操作符进行计算的结果是大不一样的。 目前我们接触了两种数据类型:字符串和数字。 字符串类型可以简单地通过引号来识别,它代表的是字符/字母/文字的概念,例如:

a = 'Hello'
b = "你好"
c = '3'

字符串用单引号或者双引号都可以,只要前后保持一致就可以 数字类型就是我们通常数学意义上的数字,它可以进一步分为整数类型和浮点数类型(也就是小数类型);     整数,也称int,没有小数点;     浮点数,也称float,有小数点,支持科学计数法;

a = 3
b = -3
c = 3.14
d = 3.0

python还有其他类型,如布尔型、列表、字典和对象,后面用到的时候我们再逐步讲解。

代码修正

回到我们的问题,我们希望使用input函数输入数字时它就给我返回数字,但实际上它返回的是一个字符串。这时候我们就需要用到python提供的类型转换的功能,尝试如下代码:

a = '32'
a = int(a)
print(a)

在这段代码中,变量a首先被赋值为字符串'32',然后我们使用int函数,把字符串'32'转换成了一个整数32并赋值给变量a,所以最终输出的是一个数字32,你可以试着输出a*2试试,看看结果到底是3232还是64. 并且int不止可以把字符串转换为数字,还可以把小数转换为整数,试试int(3.14)吧 理解了这部分内容后,我们就可以把狗龄计算器中的问题修复了,完整代码为:

dog_name = input("请问你的狗狗叫什么名字? ")
dog_age = input("请问你的狗狗几岁了? ")
human_age = int(dog_age) * 7  #增加int函数,将字符串转换为数字再进行乘法
print(human_age)

完成这部分内容后,我们就进入了最后一步!

对用户友好的输出

当我们计算出来狗狗对应到人类的年龄之后,我们就需要把狗狗的名字跟年龄组合在一起输出了,为此我们首先复习一下print函数,在之前的例子中我们用了很多次print,但是都是输出一个内容:

print("Hello")
print(32)

那怎么样才能输出很多内容呢?有两种方法:

  1. 利用之前学到的加号连接符,可以把多个字符串连接在一起,比如:
print("Hello" + "World")
a = "Hello"
b = "World"
print(a + b)

这里要注意的是加号连接符只能连接两个字符串,如果是一个数字一个字符串是没办法连接的,会报错,比如:

print("Hello" + 32)
  1. 第二种方法是利用print函数的进阶功能:通过逗号隔开的方法可以给print函数传递多个内容,print函数会把他们用空格连在一起后输出,例如:
print("Hello" , 32 , "World")

最终狗龄计算器的完整代码为:

dog_name = input("请问你的狗狗叫什么名字? ")
dog_age = input("请问你的狗狗几岁了? ")
human_age = int(dog_age) * 7  #增加int函数,将字符串转换为数字再进行乘法
print("你的狗狗",dog_name,"对应到人类年龄是",human_age,"岁")

思维训练

在结束这一章之前,我们进行两个小的思维训练,考验一下你对变量的理解程度:

  1. 变量交换: 这时候我们得到的结果为:32 18,通过什么样的方法才能在运行print(a,b)的时候得到18 32这样的结果?
    a = 32
    b = 18
    print(a,b)
  1. 变量定义
    a = "Hello"
    a = Hello

当我去掉Hello外面的引号时会怎么样?

判断语句

到目前为止,我们的程序还不算很有趣,我们的代码还只是一组简单的语句,只会按照顺序从上到下依次执行,其实电脑之所以能做很多自动化的任务,是因为它可以自己做条件判断。在本章中我们将通过一个石头剪刀布的游戏来掌握判断语句。 首先我们来拆解一下这个游戏,也就是分析一下游戏由哪几部分组成:

  1. 用户启动游戏:     A. 电脑确定它的选择;
  2. 游戏开始:     A. 得到用户的选择;     B. 检查用户的选择,如果是非法的(不是石头、剪刀或者布),就返回到步骤2A;如果与电脑的选择相同,就设置为平局,转向步骤3;     C. 按规则确定谁是赢家;
  3. 游戏结束:     A. 告诉用户谁是赢家,另外给出电脑的选择; 整个过程可以通过流程图表示出来:
graph TD
1((开始)) --> A
A[电脑做出它的选择] --> B(得到用户的选择)
B --> C{检查选择}
C -->|相同| D[确定为平局]
C -->|不同| E[按规则确定赢家]
C -->|非法| B[得到用户的选择]
D --> F[显示赢家]
E --> F[显示赢家]
F --> 2((结束))

电脑的选择

游戏开始的第一步,我们先让电脑选择石头或者剪刀或者布,当然了这个选择一定要是随机的,并且在最终答案揭晓之前玩家是不知道的。接下来我们首先来学习一下在python中如何得到随机数

生成随机数

python提供了很多内置的功能,这些内置的功能以模块(也称为库)的形式存在,模块的概念我们以后还会深入讲解,这里我们先学习如何使用。对于随机数,要使用的模块叫random模块,用法如下:

import random

import是导入的意思,random就是随机数模块的名称;导入随机数模块之后就可以使用生成随机数的功能了,用法如下:

random.randint(0.2)

这句话的意思是生成0到2范围内的一个随机整数,有可能是0,1或者2. 你可以试一下如下的代码:

import random
random_choice = random.randint(0,2)
print(random_choice)
print("电脑选择的是:", random_choice)

现在我们已经实现了随机的功能,但是随机出来的是0,1,2并不是我们期望的石头剪刀布,所以接下来我们要尝试把生成的随机数转换一下,这时候就得学习本章的核心主题了:判断语句,通过判断语句让程序能够自己做决定。

True of False

为了让程序能够做决定,首先它得知道一件事儿是对的还是错的,这个对和错的表示方法跟英语判断题里用的T和F是同样的单词:T就是True的缩写,也就是对的、成立的;F就是False的缩写,也就是错的、不成立的。这个True和False在Python里是一个全新的类型,叫布尔值,这个了解即可,但是需要特别注意的是True和False的首字母是大写的,并且没有加引号。 考考你,如果加了引号是什么数据类型? 你可以在IDLE中执行如下代码,直观体验一下True和False是如何产生的:

age = 20
age > 18
age = 18
age > 18
age = 10
age >= 18
age == 18
age != 18
判断语句if

认识了True和False这个布尔类型之后我们就可以进一步学习怎么让程序做决定了,这时候if语句就出场了,if语句结合布尔类型就可以实现判断的功能,比如下面的例子: 输入用户年龄,根据年龄打印不同的内容,在python程序中,用if语句实现:

age = 20

if age >= 18:
    print('your age is', age)
    print('adult') #adult:成人

根据python的缩进规则,如果if语句判断是True,就把缩进的两行print语句执行了,否则,什么也不做。也可以给if添加一个else语句,意思是,如果if判断是False,不要执行if的内容,去把else执行了:

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager') #teenager:青少年

注意不要少写了冒号:。 当然上面的判断是很粗略的,完全可以用elif做更细致的判断:

age = 3

if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')  #kid:小孩子

elifelse if的缩写,完全可以有多个elif,所以if语句的完整形式就是:

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elifelse,所以,请测试并解释为什么下面的程序打印的是teenager:

age = 20

if age >= 6:
    print('teenager')
elif age >= 18:
    print('adult')
else:
    print('kid')
回到石头剪刀布

有了判断功能之后,我们就可以优化我们的代码了,通过if语句判断得到的是0的话,则转换成“石头”,依次类推,代码如下:

import random

random_choice = random.randint(0,2)
#print("电脑选择的是:", random_choice) 将这一行注释掉,通过下面的代码进行转换

if random_choice == 0:
    computer_choice = '石头'
elif random_choice == 1:
    computer_choice = '布'
else:
    computer_choice = '剪刀'
    
print("电脑选择的是",computer_choice)
得到玩家的选择

现在电脑已经做出了自己的随机选择,接下来该玩家做出选择了,这时候就用到我们之前学过的input函数,让玩家用户自己来输入自己的选择并且把输入的内容存储到一个变量中。代码如下:

import random

random_choice = random.randint(0,2)

if random_choice == 0:
    computer_choice = '石头'
elif random_choice == 1:
    computer_choice = '布'
else:
    computer_choice = '剪刀'
    
#print("电脑选择的是",computer_choice) 把这一行注释掉,不提前暴漏电脑的选择

user_choice = input('石头、剪刀还是布?')
print('你选择的是:',user_choice,";电脑选择的是:",computer_choice)

检测平局

得到了电脑的选择和玩家的选择之后就可以进行下一步了,根据我们的流程图,这里有3种可能:

  • 玩家和电脑做了相同的选择,我们得到一个平局;
  • 玩家和计算机做了不同的选择,我们需要确定谁是赢家;
  • 用户输入一个非法的选择,需要重新输入;

我们首先完成第一步检测平局,利用前面学到的if判断语句,我们可以判断一下电脑的选择跟玩家的选择是否相同,如果相同的话则设定为平局,代码如下:

import random
random_choice = random.randint(0,2)
if random_choice == 0:
    computer_choice = '石头'
elif random_choice == 1:
    computer_choice = '布'
else:
    computer_choice = '剪刀'
user_choice = input('石头、剪刀还是布?')
print('你选择的是:',user_choice,"电脑选择的是",computer_choice) #也可以把这一段注释或者删除掉
if computer_choice == user_choice:
    winner = '平局'
    print(winner)

其中winner变量是我们用来记录最后的赢家的,如果是平局的话也暂时存在这个变量里,后面我们再来进一步优化代码。你可以试试运行这段代码,看能不能得到平局的情况呢?友情提示,有可能需要运行很多次才可以,这时候你一定很像让程序自动重复运行,别慌,后面我们会讲解重复运行的功能。

谁是赢家?

如果电脑选择跟玩家选择不相同的话,就得判断出来谁是赢家了,这时候我们需要首先梳理一下电脑赢的情况有哪些:

  • 如果电脑选择布,并且玩家选择石头,那么电脑赢;
  • 如果电脑选择石头,并且玩家选择剪刀,那么电脑赢;
  • 如果电脑选择剪刀,并且玩家选择布,那么电脑赢;

接下来我们也可以按照同样的方法梳理出玩家赢的情况,但是有更简单的方法:我们已经把平局和电脑赢的情况都梳理出来了,那么剩下的是不是就都是玩家赢的情况了呢? 在具体代码之前,我们需要学习一个新知识:怎么在Python里面表示并且?这个也很简单,用and这个单词,比如:

age > 5 and age < 10 

更进一步,Python中除了可以表示并且,还有两个跟并且类似的经常用的关键词:or和not. or是或者的意思,比如:

age > 5 or age == 5 

not是反过来的意思,比如:

not (age < 5) 

思考一下当age=6时上面的表达式的结果是什么?当age=11时结果又是什么?当age=5时结果又是什么?

回到我们的石头剪刀布的游戏,我们利用and并且的功能来实现谁是赢家的判断,代码如下:

import random

random_choice = random.randint(0,2)

if random_choice == 0:
    computer_choice = '石头'
elif random_choice == 1:
    computer_choice = '布'
else:
    computer_choice = '剪刀'
    
user_choice = input('石头,剪刀,布?')

if computer_choice == user_choice:
    winner = '平局'
elif computer_choice == '布' and user_choice == '石头':
    winner = '电脑'
elif computer_choice == '石头' and user_choice == '剪刀':
    winner = '电脑'
elif computer_choice == '剪刀' and user_choice == '布':
    winner = '电脑'
else:
    winner = '玩家'
    
print(winner,'赢了!')  

多运行几遍程序,把三种结果都尝试出来,是不是会出现“平局赢了”这样奇怪的字眼,所以接下来我们对最终的结果进行一下优化。

优化输出结果

如果平局,我们输出:平局!我们都选择了xx。如果没有平局,我们输出:xx赢了,玩家选择了xx,电脑选择了xx。 代码如下:

#print(winner,'赢了!')
if winner == '平局':
    print("平局!我们都选择了",user_choice)
else:
    print(winner,"赢了,玩家选择了",user_choice,",电脑选择了",computer_choice)
处理非法输入

我们希望运行程序的时候玩家输入的是石头或者剪刀或者布,但实际上玩家会不会输入其他内容呢? 大概率是有可能的,你也可以试试会有什么结果。那如何知道用户输入的内容是不是非法的呢?我们也可以通过判断语句来实现,代码如下:

user_choice = input('石头,剪刀,布?')

if user_choice != '石头' and user_choice != '布' and user_choice != '剪刀':
      user_choice = input('输入错误,请重新输入!石头,剪刀,布?')

这段代码比较长,要好好理解一下,它的意思是如果玩家的输入不是石头并且不是布并且不是剪刀,那么意味着玩家的输入是非法输入,这时候程序就提示玩家:输入错误,请重新输入了。 尝试运行代码,有没有发现什么问题?当我们第二次输入也是非法的时候,就不会再提示我们重新输入了!怎么解决这个问题,让用户不断输入直到输入正确的内容才进行后续的判断赢家呢?这个就用到Python中的循环语句了,把我们程序中的if修改为while就可以实现这个功能了,这样你就完成了石头剪刀布的游戏了,快去试试吧!关于循环语句while的具体用法我们到下一章中详细讲解。

import random
random_choice = random.randint(0,2)
if random_choice == 0:
    computer_choice = '石头'
elif random_choice == 1:
    computer_choice = '布'
else:
    computer_choice = '剪刀'
   
user_choice = input('石头,剪刀,布?')
while user_choice != '石头' and user_choice != '布' and user_choice != '剪刀':
    user_choice = input('输入错误,请重新输入!石头,剪刀,布?')
    
if computer_choice == user_choice:
    winner = '平局'
elif computer_choice == '布' and user_choice == '石头':
    winner = '电脑'
elif computer_choice == '石头' and user_choice == '剪刀':
    winner = '电脑'
elif computer_choice == '剪刀' and user_choice == '布':
    winner = '电脑'
else:
    winner = '玩家'
   
#print(winner,'赢了!')
if winner == '平局':
    print("平局!我们都选择了",user_choice)
else:
    print(winner,"赢了,玩家选择了",user_choice,",电脑选择了",computer_choice)

循环语句

在石头剪刀布游戏的最后我们使用了while语句来实现重复判断的功能,接下来我们就来深入研究一下while语句的用法。while语句是为了让代码实现重复执行的效果,值得一提的是Python中还有另一个实现重复执行效果的循环语句for语句,这个我们后面也会讲解到。

基本用法

首先来看一下while语句的用法:

i = 1
while i <= 10:
    print('这么简单,我会了!')
    i = i + 1

在这个例子中,我们首先设定了一个计数器i并且把初始值设定成了1,while语句后面跟着一个条件:i <= 10,如果判定条件成立的话,则会执行里面的两行代码,如果条件不成立的话,那么while语句就结束了。 更进一步,我们可以把计数器i也打印出来,变成一个报数的程序:

i = 1
while i <= 10:
    print('编号:',i)
    i = i + 1

我们也可以让报数倒着来,代码如下:

i = 10
while i >0 :
    print('编号:',i)
    i = i - 1

仔细观察两段代码,能发现几处不同呢? 接下来我们再来看一个例子:计算1+2+3+...+100的结果,相信大家对这个一定很熟悉,这个怎么通过编程来实现呢?执行如下的代码看是不是5050:

sum = 0
n = 1
while n <= 100:
    sum = sum + n
    n = n + 1
print(sum)

while循环语句可以跟之前学过的if判断语句相结合,比如计算1到100之间所有奇数的和:

sum = 0
n = 1
while n <= 100:
    if n%2 == 1:
        sum = sum + n
    n = n + 1
print(sum)

有些时候,如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用Ctrl+C退出程序,或者强制结束Python进程。请试写一个死循环程序。

break

在循环中,break语句可以提前退出循环。例如,本来要循环打印1~100的数字:

n = 1
while n <= 100:
    print(n)
    n = n + 1

上面的代码可以打印出1~100。如果要提前结束循环,可以用break语句:

n = 1
while n <= 100:
    if n > 10: # 当n = 11时,条件满足,执行break语句
        break # break语句会结束当前循环
    print(n)
    n = n + 1

执行上面的代码可以看到,打印出1~10后,程序结束,可见break的作用是提前结束循环。

continue

在循环过程中,也可以通过continue语句,跳过当前的这次循环,直接开始下一次循环。

n = 0
while n < 10:
    n = n + 1
    print(n)

上面的程序可以打印出1~10。但是,如果我们想只打印奇数,可以用continue语句跳过某些循环:

n = 0
while n < 10:
    n = n + 1
    if n % 2 == 0: # 如果n是偶数,执行continue语句
        continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行
    print(n)

执行上面的代码可以看到,打印的不再是1~10,而是1,3,5,7,9。 可见continue的作用是提前结束本轮循环,并直接开始下一轮循环。

海龟画图

学习了while循环语句之后,我们来结合Python中内置的海龟画图模块来做一些有趣的程序,首先来尝试一下如下的代码,熟悉下海龟画图的基本用法:

import turtle           #导入海龟画图模块

turtle.forward(100)     #前进100步
turtle.right(90)        #向右转90度

turtle.forward(100)
turtle.right(90)

turtle.forward(100)
turtle.right(90)

turtle.forward(100)
turtle.right(90)

turtle.done()           #结束画图

通过如上的代码我们就绘制出了一个正方形,那如果想要绘制多个正方形怎么办呢?当然可以复制和粘贴,不过既然学习了while循环语句,我们就要利用它来实现这个效果了,代码如下,试试效果吧:

import turtle           #导入海龟画图模块

i = 1
while i<=10:
    turtle.forward(100)     #前进100步
    turtle.right(90)        #向右转90度
    turtle.forward(100)
    turtle.right(90)
    turtle.forward(100)
    turtle.right(90)
    turtle.forward(100)
    turtle.right(90)
    turtle.right(36)
    i = i + 1
turtle.done()           #结束画图

这样我们就实现了画10个正方形的效果,如果你觉得速度太慢的话可以添加一行代码调节海龟画图的速度:

turtle.speed(0)

speed是速度的意思,括号里面可以填0~10的整数,从1到10,速度越来越快,0是最快的。另外,你知道怎么改成画36个正方形吗?大胆尝试一下。

细心的同学可能也发现了前进100步和向右转这两行代码重复好好几次,不能优化吗?答案是可以的:

import turtle           #导入海龟画图模块
turtle.speed(0)
i = 1
while i<=36:
    j = 1
    while j<=4:
        turtle.forward(100)     #前进100步
        turtle.right(90)        #向右转90度
        j = j + 1
    turtle.right(10)
    i = i + 1
turtle.done()           #结束画图

这种写法叫做嵌套重复,也就是两个重复执行的循环语句套在了一起,你能想清楚它的执行逻辑吗?这个很重要,深入思考一下。

最后再给大家提供两个有趣的海龟画图的例子,大家可以试着编程运行一下看看效果。

import turtle           
turtle.speed(0)
i = 1
while i<=10:
    turtle.forward(60+i*20)     
    turtle.right(90)        
    turtle.forward(60+i*20)
    turtle.right(90)
    turtle.forward(60+i*20)
    turtle.right(90)
    turtle.forward(60+i*20)
    turtle.right(90)
    turtle.penup()
    turtle.goto(-i*10,i*10)
    turtle.pendown()
    i = i + 1
turtle.done()           
import turtle           
turtle.speed(0)
i = 1
while i<=50:
    turtle.forward(60+i*10)     
    turtle.right(90)        
    turtle.forward(60+i*10)
    turtle.right(90)
    i = i + 1
turtle.done()           

列表和迭代

在前面的章节中我们已经大量使用了变量,在变量里我们存储过整数、浮点数、字符串等这些数据类型的值,这些数据类型被称为基本类型,它们的特点是只能存储一个值,比如你没办法把1和2同时存在变量a里面。如果想要往变量里存储多个值的话,就需要用到本章的主角了:列表!学习列表之后,我们就可以写出比较复杂的程序了,不过也不用担心列表很难,先通过一个趣味案例来体验一下列表。

趣味短语

在这个程序中,我们从3个列表中随机挑选出了3个词语,然后把它们组合成了一个句子,因为是随机挑选的,所以有时候会有奇怪的有趣的短语出现,来试试吧。

import random
#verbs: 动词  
verbs = ['吃','踢','跑','走','写','看','逛']
# adjectives: 形容词
adjectives = ['漂亮的','明亮的','绿色的','白色的','光滑的','椭圆的','萌萌的']
# nouns: 名词
nouns = ['饭','球','路','作业','电视','商场','房子']
verb = random.choice(verbs)
adjective = random.choice(adjectives)
noun = random.choice(nouns)
# phrase: 短语
phrase ='屏幕前的你 ' + verb + ' '+ adjective + ' ' + noun
print(phrase)

以上这个程序就用到了3个列表:

  • 存储动词的列表
  • 存储形容词的列表
  • 存储名词的列表 然后通过random.choice()这个函数从列表中随机挑选了一个元素,再通过加号把他们连接在一起就组成了一个短语。怎么样,列表的基本用法还是比较简单的吧?
列表操作

接下来我们以班级里同学名字作为案例来详细讲一下列表的用法。 首先, 列出班里所有同学的名字,就可以用一个list表示:

>>> names = ['张三', '李四', '王五']
>>> names
 ['张三', '李四', '王五']

变量names就是一个list。用len()函数可以获得list元素的个数:

>>> len(names)
3

用索引来访问list中每一个位置的元素,记得索引是从0开始的:

>>> names[0]
'张三'
>>> names[1]
'李四'
>>> names[2]
'王五'
>>> names[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

当索引超出了范围时,Python会报一个IndexError错误,所以,要确保索引不要越界,记得最后一个元素的索引是len(names) - 1。如果要取最后一个元素,除了计算索引位置外,还可以用-1做索引,直接获取最后一个元素:

>>> names[-1]
'王五'

以此类推,可以获取倒数第2个、倒数第3个:

>>> names[-2]
'李四'
>>> names[-3]
'张三'
>>> names[-4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

当然,倒数第4个就越界了。list是一个可变的有序表,所以,可以往list中追加元素到末尾:

>>> names.append('赵六')
>>> names
['张三', '李四', '王五','赵六']

也可以把元素插入到指定的位置,比如索引号为1的位置:

>>> names.insert(1, '孙七')
>>> names
['张三', '孙七', '李四', '王五','赵六']

要删除list末尾的元素,用pop()方法:

>>> names.pop()
'赵六'
>>> names
['张三', '孙七', '李四', '王五']

要删除指定位置的元素,用pop(i)方法,其中i是索引位置:

>>> names.pop(1)
'孙七'
>>> names
['张三', '李四', '王五']

要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:

>>> names[1] = '周八'
>>> names
['张三', '周八', '王五']

列表list里面的元素的数据类型也可以不同,比如:

>>> L = ['Apple', 123, True]

list元素也可以是另一个list,比如:

>>> s = ['python', 'java', ['asp', 'php'], 'scratch']
>>> len(s)
4

要注意s只有4个元素,其中s[2]又是一个list,如果拆开写就更容易理解了:

>>> p = ['asp', 'php']
>>> s = ['python', 'java', p, 'scratch']

要拿到'php'可以写p[1]或者s[2][1],因此s可以看成是一个二维数组,类似的还有三维、四维……数组,不过很少用到。如果一个list中一个元素也没有,就是一个空的list,它的长度为0:

>>> L = []
>>> len(L)
0
实际案例

接下来我们通过一个泡泡公司的案例来深入学习列表,泡泡公司通过不同的配方研制了不同的泡泡液,每种泡泡液能吹出的泡泡数量是不一样的,因为有很多种方案所以要通过列表来存储,代码如下:

scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]

我们要实现的功能是把每一种泡泡方案的编号和得分以此输出,然后输出泡泡方案的总个数、最高分以及最高分对应的方案编号是哪个。

迭代列表

我们的第一个小任务是把列表中的每一个元素依次取出来,这个过程我们也称为迭代列表,我们可以使用之前学过的while循环来做,代码如下:

#回顾while循环的用法
scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]
i = 0
length = len(scores)
while i < length:
    print('泡泡方案#',i,'的得分为:',scores[i])
    i= i + 1

输出的结果很正确,但是有一个小问题你注意到了吗?输出中#后面有一个多余的空格,导致文字并不连续:

泡泡方案# 35 的得分为: 44

之所以会有这个问题,是因为print函数虽然可以通过增加逗号的形式将多个内容一起输出,但是会在各个内容中间添加一个空格。我们可以通过加号链接的方式来解决这个问题,但是注意加号只能把两个字符串连接在一起,所以需要把整数类型的i转换为字符串之后再进行连接:

scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]
i = 0
length = len(scores)
while i < length:
    print('泡泡方案#'+ str(i),'的得分为:',scores[i])
    i= i + 1
for循环,迭代列表的首选方法

虽然使用while循环是可以迭代处理列表额,不过首选的方法其实是使用一个for循环。可以把for循环想成是while循环的兄弟,这两个循环实际上做的是同样的事情,只不过,如果要基于某个条件循环时通常使用while循环,如果要迭代处理一个列表时往往会使用for循环。以上面的同学名字为例:

names = ['张三', '李四', '王五']
for name in names:
    print(name)

执行这段代码,会依次打印names的每一个元素:

张三
李四
王五

所以for i in ...循环就是把每个元素代入变量i,然后执行缩进块的语句。再比如我们想计算1-10的整数之和,可以用一个sum变量做累加:

sum = 0
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    sum = sum + i
print(sum)

如果要计算1-100的整数之和,从1写到100有点困难,幸好Python提供一个range()函数,可以生成一个整数序列,再通过list()函数可以转换为list。比如range(5)生成的序列是从0开始小于5的整数:

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

回到计算1-100的整数之和这道题,通过for语句就可以这么写了:

sum = 0
for i in range(101):
    sum = sum + i
print(sum)

运行上述代码,结果是不是也是5050呢。 另外,for循环的写法经常用在重复多少次的场景中,比如重复说5遍“我学会了!”:

for i in range(5):
    print('我学会了!')

是不是比while语句写出重复执行几次更简单一些呢?

range进一步学习

range函数可以生成从0到某个数的序列,也可以创建任意类型的数字区间。下面给出几个例子:

增加起始数:

range函数支持填入两个参数,第一个为起始数,第二个为结束数,第一个不填的话则默认为0,所以range(5)就相当于range(0,5):

range(5,10)
# 创建一个从5开始到10结束,包含5不包含10的序列,也就是5,6,7,8,9,10
增加步长

range函数也支持填入三个参数,第三个参数为步长,不填的话默认为1,所以range(5)相当于range(0,5),也相当于range(0,5,1):

range(3,10,2)
# 创建一个从3开始到10结束,包含5不包含10的步长为2的序列,也就是3,5,7,9
支持倒数
range(10,0,-1)
# 创建一个从10开始到0结束,包含10不包含0的步长为-1的序列,也就是10,9,8,7,6,5,4,3,2,1
回到泡泡方案

学过了for循环之后,我们迭代泡泡方案的方法就可以这么写了:

scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]
length = len(scores)
for i in range(length):
    print('泡泡方案#'+ str(i),'的得分为:',scores[i])
最高分

迭代输出泡泡方案的编号和得分之后就该输出方案的个数和最高分了,个数比较简单,用len函数求一下列表的长度就可以,最高分怎么求呢? 我们的思路是这样的,新建一个变量high_score专门用来记录最高分,一开始把它设置为0,然后在迭代泡泡列表的时候检查一下当前得分是不是大于high_score,如果确实大于,就把当前得分存到high_score中。然后迭代结束的时候high_score中存储的就是列表中所有元素的最高分了! 代码如下:

# 求列表里面的最高分
scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]
high_score = 0
length = len(scores)
for i in range(length):
    print('泡泡方案#'+ str(i),'得分为:',scores[i])
    if scores[i] > high_score:
        high_score = scores[i]
print("泡泡方案的个数为:",length)
print("泡泡方案的最高分为:",high_score)

有了最高分的思路,你能举一反三求出来最低分吗?

最高分方案编号

有了最高分之后,我们还得进一步找到哪个方案是最高分,这时候就得注意了,是不是有可能并列最高分呢? 所以找最高分编号的时候就不能想找最高分一样用变量来存储了,必须得使用列表以解决有可能有多个编号是最高分的情况。 我们的思路是这样的,新建一个列表类型的变量best专门用来记录最高分方案编号,一开始把它设置为空,找到编号之后把它添加到列表中,然后再迭代泡泡列表的时候检查一下当前得分是不是等于最高分,如果等于的话就把它的编号添加到best列表中。然后迭代结束的时候我们就找到了所有具有最高分的方案编号。代码如下:

# 求列表里面的最高分
scores = [60,50,60,58,54,54,58,50,52,54,48,69,34,55,51,52,44,51,69,64,66,55,52,61,46,31,57,52,44,18,41,53,55,61,51,44]
high_score = 0
length = len(scores)
for i in range(length):
    print('泡泡方案#'+ str(i),'得分为:',scores[i])
    if scores[i] > high_score:
        high_score = scores[i]
print("泡泡方案的个数为:",length)
print("泡泡方案的最高分为:",high_score)
# 求最高分的编号
best_solutions = []
for i in range(length):
    if scores[i] == high_score:
        best_solutions.append(i)
print('最优方案的编号是:',best_solutions)
Last Updated:
Contributors: aibokalv