for循环的基础操作

循环是计算机程序的三大语句结构之一。

它是在满足条件的情况下,反复执行某一段代码的计算过程。

假设,现在我们需要输出以下列表中的每个元素,你会怎么做呢?

numberList = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

可以通过索引,将列表中的元素一个一个的输出。

如果列表中的元素不止五项,而是几十项,甚至是几百项,我们还要大量重复编写print() 和列表索引么?这可太麻烦了。

接下来,我们试着用【循环】简化这段代码。

numberList = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
for number in numberList:
    print(number)

原本需要编写 10 行的代码,现在使用【循环】后,编写方便了很多。

在 Python 中,循环语句有两类:
for 循环和 while 循环

for 循环的结构

numberList = [10, 20, 30, 40, 50, 60]

for number in numberList:
    print(number)

代码的作用
这三行代码使用了 for 循环将列表 numberList 里面的所有元素全部输出出来。

for
使用关键字 for,表明要在这里开始执行“for循环”的代码结构。

in
使用关键词 in,和 for 搭配,表明我们要把 in 后面的列表里面的数据元素赋值给前面的变量。

变量
表示一个变量,在 for 循环里面用来存储列表中的元素。
在本例代码中,列表 numberList 中有 6 个元素,变量 number 会被赋值 6 次。

列表
列表中里面的元素会被分别赋值给变量,直到最后一个元素完成赋值,循环才结束。

冒号
循环语句的固定格式,表明接下来缩进的代码是每次循环都要执行的。

缩进
同样缩进的代码就是一个代码块,在每次循环中都要执行。
在这里,建议缩进四个空格,和 if 语句类型的缩进一样,保持同一种代码风格。

循环内
循环内的代码块,直到列表 numberList 中的元素被全部赋值完,循环才结束。
在本例中,由于列表 numberList 中的元素有 6 个,print()就要执行 6 次。

代码小结
通过如下格式在代码中使用for循环

# TODO 定义列表fruitList
fruitList = ["apple", "grape","cherry"]

# TODO for循环列表fruitList,将元素赋值给变量fruit
for fruit in fruitList :
    # TODO 输出变量fruit
    print(fruit)
# 使用 for 循环,利用切片获取列表中的第二项到第六项元素,分别赋值给一个变量 number,然后使用 print() 输出这个变量。

# 定义列表numberList
numberList = [10, 20, 30, 40, 50, 60]

# TODO for循环列表中的第二项到第六项元素
for number in numberList[1:] :
    # TODO 输出列表的元素
    print(number)

for 循环的运行流程

当程序执行完 for 循环后,如果同一层级(缩进一致)还有代码未执行,则按照顺序,继续自上而下执行。

本例中,第2行和第3行的循环,执行 6 次以后,列表 numberList 中所有元素都被访问完了,for 循环结束。
变量 number 被赋值 6 次,循环结束后,变量 number 的值为 60。

程序继续执行下面和 for 循环处于同一层级代码,输出变量 number,在运行结果中就输出了 60。

for 循环的灵活之处在于,它会根据列表中的元素个数,自动调节循环的次数。
也就是说,for 循环能自动遍历一个列表里面的所有元素。

遍历

遍历是指通过某种顺序对一个数据结构中的所有元素进行访问。

for循环不仅可以遍历列,还可以遍历字典、元组、甚至字符串等数据结构。
遍历元组和字符串与遍历列表的代码几乎一样,也是逐个获取元组或字符串的每个字符。

for 循环遍历字典稍微有一些区别。
字典是键值对的组合,那么对字典的遍历就包含【键,值,键和值】三种情况。

遍历字典的键
for 循环遍历字典的键,有两种方法可以使用:

  1. for 循环遍历字典;
    这个方法和 for 循环遍历列表的格式类似。

  2. for循环遍历字典中的所有键;
    使用 for 循环遍历 dict.keys(),将字典中的键赋值给变量,再通过 print() 输出变量。


遍历字典的值
遍历字典的值,可以通过查字典的方式,也就是通过字典的键找到对应指定的值。
首先使用 for 循环遍历字典,将键赋值给变量,通过dict[键]的方式找到对应的值并赋值给新的变量

接着使用 print()输出这个变量,即可遍历字典的值。

遍历字典的键和值
上面演示的是使用 for 循环遍历字典的键和字典的值,如果想要同时输出字典的键和值,该怎么办呢?
这时,可以在循环内部分别输出字典的键和对应的值。

注意,在 for 循环中,一次循环会把循环内的代码全部执行完后,再开始下一次循环。

在本例中,for 循环遍历字典productItems,在第一次循环中,变量 key 被赋值为"口香糖"。
进入循环中,第3行代码获取到"口香糖"对应的值 15,并赋值给变量 value,在第4行和第5行分别输出"口香糖"和15。
接着进入第二次循环,变量 key 被赋值为"可乐",就这样执行完循环内的代码,再开始下一次循环,直到循环结束。

# 修改年龄
# 刘老师在录入学生年龄时,不小心输入错了学生年龄,现在她想要把学生的年龄批量修改,这该如何操作呢?
# 1. 首先定义一个叫作 studentAge 的字典,{"Gary": 14, "Adam": 13, "Jack": 15, "Max":13, "Tim":14}。
# 2. for 循环遍历字典 studentAge,将字典的键赋值给变量key;
# 2.1 利用字典键查找值的方法,将字典中全部的值修改为 16。
# 3. for 循环结束后,输出字典studentAge。

# TODO 定义字典studentAge
studentAge = {"Gary": 14, "Adam": 13, "Jack": 15, "Max":13, "Tim":14}

# TODO for循环字典studentAge
for key in studentAge :
    # TODO 修改字典的值为16
    studentAge[key] = 16

# TODO 输出字典studentAge
print(studentAge)
studentAge = {"Gary": 14, "Adam": 13, "Jack": 15, "Max":13, "Tim":14}
for key in studentAge :
    print(key)
    print(studentAge[key])

for循环的复杂应用

学习了 for 循环遍历列表、字典等数据的方式。

了解学习下for 循环与“累加” 、if 判断和“计数器”的结合运用。

学过运用四则运算,计算 a 和 b 的和。

如果,要计算列表 jdList 中所有元素的和,该怎么操作呢?

这种情况下,了解下"累加"的概念。

什么是“累加”呢?

例如,往瓶子里不断地放硬币的过程,就是“累加”。

for 循环与“累加”

jdList = [3, 1.5, 4, 2]
total = 0
for price in jdList:
    total = total + price
print(total)

代码的作用
这5行代码的功能就是,计算列表中的所有元素的总和并输出。

定义列表

第1行定义了列表 jdList ,列表中的四个元素都是可计算的数值(整型或浮点型)。

初始值

我们需要用一个变量来存储总和,第2行定义变量 total ,将0赋值给变量,这个过程就是设置初始值。

注意:这里的初始值需要定义在 for 循环的外侧,若定义在 for 循环中,每次循环变量都会重新赋值。

遍历列表

第3行使用for...in... 结构遍历列表 jdList ,依次取出每个元素。

累加

第4行使用加法,计算 total 和 price 的和,再赋值给 total。

注意:根据四则运算规则,先计算等号("=")右边内容,再将计算结果赋值给左边变量。

(累加计算过程)
for循环第一次取出的元素price的值为3

然后第一次对列表中的元素进行累加,total的初始值为0,price的值为3,两者相加和为3,赋值给total

第二次循环时,price的值为1.5

total的值为3,两者相加和为4.5,再赋值给total

第三次循环时,price的值为4

total的值为4.5,两者相加为8.5

最后一次循环,price的值为2

total的值为8.5,两者相加的结果为10.5

循环结束后,print输出的total就是10.5

结果

当 for 循环遍历结束后,此时,total 的值为最后一次计算的结果。

第5行,使用 print() 输出的就是列表中四个数据的总和。

代码小结

当使用累加来计算时,就需要这几部分


以上就是一个“累加”的应用演示。

但在列表的操作中,不仅有总和的计算。接下来,学习记录元素在列表中位置的方法。

计数器的应用

例如:班主任有一个学生名单,需要按照顺序输出,第1名是xx,第2名是xx。

一般我们会使用索引,一行行输出,点击「run」直接运行即可。

names = ["Tom", "Tim", "Amy", "Eva"]
print(f"第1名是{names[0]}")
print(f"第2名是{names[1]}")
print(f"第3名是{names[2]}")
print(f"第4名是{names[3]}")

但是这样一行行的输出太繁琐了。

为了解决这个问题,可以使用“计数器”来记录当前的遍历位置。

(什么是“计数器”? “计数器”与“累加”的用法类似,在日常生活中,用来统计当前项目的进度)

因此,班主任输出学生排名,可以在遍历姓名的同时,使用“计数器”统计当前位置。

(计数器计算过程)

for循环第一次遍历列表,

然后使用count进行计数,此时count的值为0,+1,赋值给count,于是count的值为1.

同时数出那names列表里的第一个元素是Tom,于是输出"第一名是Tom"

第二次继续遍历

每次遍历count的值就加1

直到遍历完成。

if判断的复杂应用

学习了“累加”和“计数器”的用法后,但是部分情况下,我们不一定会对列表中的每个元素都进行累加,如果只取部分,该怎么处理呢?

如图所示,列表中已售罄商品使用"-"表示,想要剔除"-",统计剩余商品总价,该怎样计算呢?

这时,需要使用 if 语句,先判断再计算。

如图所示,逐个取出列表中的元素,使用 if 判断,元素不等于"-"时,再进行累加。

整理前面的思路,剔除"-"计算列表 jdList 的商品总价代码如图。

第4行,if 判断 price 不等于 "-" 时,使用累加计算总价。

在 for 循环中使用 if 语句时,需要注意缩进。

第一个缩进,上节课学过 for 循环中的代码需要增加缩进,表明是一个代码块。

第二个缩进,使用 if 语句时,语句里面的内容也需要增加缩进。

使用 for 循环和 if 语句时,需要注意 print() 的位置。

  1. 当 print() 在 for 循环中缩进四个空格时,按照代码执行顺序,遍历每个元素后再输出。

  1. 当 print() 位置在 if 语句的代码中时,表明 print() 是 if 代码块中的内容。
    只有在 if 判断的情况成立时,才会执行 print() 。

  1. 当 print() 位置与 if 语句缩进相同,按照代码执行的顺序,先执行 if 语句块,然后执行 print() 。
    因此,这里输出的内容也是列表中所有的元素。

  1. 当 print() 位置与 for 循环缩进相同时,按照代码执行顺序,循环结束后,再执行 print() 语句。
    因此,输出的内容为最终结果。

小练习 - 奇数的个数

要求:

  1. 定义变量 count ,初始值为0,用于计算奇数的个数;

  2. 使用 for 循环遍历列表,在循环中使用 if 语句判断,当元素为奇数时,将计数器 count 的值加一。

  3. 循环结束后,使用 print() 输出 count 。

# 定义numbers存储
numbers = [33.2, 4, 5, 7, 1, 2.8, 7, 5]

# 定义count初始值为0
count = 0

# 遍历列表,使用 if 判断num取模等于1时
# count计数加1,输出最终个数
for num in numbers:
    if num % 2 == 1:
        count = count + 1
print(count)

小练习 - 奇数的和

要求:

  1. 定义变量 result ,初始值为0,用于存储所有奇数的和;

  2. 使用 for 循环遍历列表,在循环中使用 if 语句判断,当元素为奇数时,将元素进行累加。

  3. 循环结束后,使用 print() 输出 result 。

# 定义列表numbers
numbers = [33.2, 4, 5, 7, 1, 2.8, 7, 5]

# 定义变量result,初始值为0
result = 0

# for循环遍历列表
for num in numbers:
    # 使用if判断,num取模的值等于1时
    if num % 2 == 1:
        # result和num相加,赋值给result
        result = result + num
# 使用print()输出结果
print(result)

一对一的字典

在Python中,将两种数据关联在一起形成一个元素, 由多个这样的元素组成的数据类型称为字典,又称为dict。
字典中的元素是不考虑排列顺序的。

组成字典元素(item)的两个数据一一对应,分别被称为键(key)值(value),所以字典的元素又称为键值对(key-value)
字典的元素只能通过键来查找对应的值,所以一个键只能对应一个值。

就像在通讯录中,我们通过联系人(键)来查找联系方式(值)。

在Python中,字典的键值对由冒号分割。冒号左边的数据为键,冒号右边的数据为值。
将多个这样的数据以逗号分割,存储到一个大括号中,就形成了一个字典类型。


products = {"口香糖": 15, "可乐": 5.5, "薯片": 45}
print(products)

代码的作用
创建一个字典“products”来存储商品信息,然后为他存储三个元素:
"15元的口香糖","5.5元的可乐","45元的薯片"。
使用print输出了整个字典。

products
一串字母,字典的变量名。

{ }
一对花括号,是字典存储数据的固定格式。

字典的键
三个字符串分别作为字典的三个键。
字典中的键可以由任意不可修改的数据类型组成(数字,字符串,元组)。
字典的键是唯一的,即一个字典不会有两个相同的键

字典的值
三个数字分别作为字典的三个值。字典中的值可以是任意数据类型。

:
三个冒号,用来连接键与值。

,
两个逗号,分割字典中的多个元素。

代码小结
当我们要定义一个dict操作时,可以使用下面的格式

作为一种数据结构,字典和列表一样,也会有查找、删除、添加、修改等功能。
但由于字典的元素,是由键值对(key-value)组成,并且字典是没有顺序的结构,因此在功能的使用上,有所不同。

查找元素
从列表中查找一个元素时,我们通过这个元素的索引,来进行查找。

字典是没有顺序的,也就没有索引,所以只能通过字典的键(key)来查找对应的值(value)

删除元素
从列表中删除一个元素时,我们使用pop()功能,通过这个元素的索引,来进行删除。
在字典中,我们依旧使用pop()功能,通过这个元素的键,来进行删除。

列表是可变的,可以通过索引修改元素,也可以通过append添加内容。
事实上,字典也是一种可变的数据类型。这意味着除了查找与删除,我们也可以对字典进行添加与修改。
但是字典的添加与修改过程与列表不同。

字典的添加与修改


products = {"name": "可乐", "type": "饮品", "price": 5}
products["other"] = "七折"
print(products)

代码的作用
创建一个字典“products”来存储选择的商品信息,然后为它存储三个键值对:
“商品的名字为可乐”,“商品的类型为饮品”,“商品的价格为5”。
第2行:为字典添加一个元素:“其它优惠活动为七折”。

字典名
要修改的字典变量名

中括号
中括号,设置要添加的键

添加的键
指定一个新的键。
字典的键可以是任何不可改变的数据类型(字符串,数字,元组等)。

=
等号=,赋值符号。

添加的值
一个字符串,表示要添加的值

修改元素
字典的键是不能重复的。当我们尝试添加一个已经存在的键时,就会将该元素覆盖。
所以对字典的修改,就是对字典的某个已经存在的键重新赋值。

代码小结
当我们要为字典添加或者修改一个元素时

以上就是对字典的查找、删除、添加与修改操作。
目前为止的两种可以修改的数据类型,即字典与列表。现在我们来比较一下这两种数据类型在操作上的不同之处。

若我们不知道字典有哪些键怎么办?
在字典中,我们还可以通过"keys()"功能获取这个字典所有的键。
keys()是字典的一个功能,它能够提取一个字典所有的键,并存储在一个类似于列表的名为dict_keys的数据中,方便我们查看该字典的键。
需要注意,keys的右边有一对空的括号。

除了使用“keys()”以外,我们也可以通过in运算来检查字典是否包含某个键。

灵活多变的列表

列表又叫List,与元组的结构类似,也可以用于存储多个类型的数据。


friendName = ["Kevin", "Tony", "Asum"]
print(friendName)

代码的作用
这2行代码定义了一个叫做“friendName”的列表,并输出了列表中的内容。

第1行代码给这个列表friendName赋值,包含三个字符串数据:Kevin,Tony,Asum。
第2行代码输出了整个列表。

friendName
变量名,用来存储这个列表。

[]
一对中括号,是定义列表的固定格式。

,
逗号,列表内部数据之间使用逗号分隔开。

空格
两个空格,这里的空格不是必须的。
但为了代码美观,建议在逗号后面加一个空格。

字符串
三个字符串,是friendName这个列表里面包含的具体数据。

代码小结
我们可以使用图中的格式输出列表中的内容。

我们知道元组中可以存储多种类型的数据。
列表与元组一样,列表中的数据元素可以是任何一种类型,如图所示,整型、浮点型、布尔数等。

除此之外,列表中的数据也可以是整型,浮点型,字符串或布尔数的任意组合。
如图所示,列表mixedList中,包含整型、浮点型和字符串三种数据类型。

取单个元素
上节学过,使用索引能够获取元组中的元素,列表与元组类似,也可以使用索引。
如图所示,取第一个元素,使用players[0],取第四个元素,就使用players[3](索引从0开始)。


players = ["小叮当", "qian", "Tang", "Max", "杰老板", "飞飞"]
print(players[2])
print(players[5])

我们知道索引用于取单个元素,如果要提取列表中的多个连续的元素,该怎么操作呢?
先学习切片的概念。

切片

编程中的切片能对元组、列表等有序数据结构进行处理,以截取数据中连续的片段,方便使用。


someLetters = ["a", "b", "c", "d", "e"]
print(someLetters[1:3])

代码的作用
这段代码做的事情是定义了一个叫做"someLetters"的列表。

第2行代码截取了列表中的第二个和第三个元素。

定义列表
第1行两侧的一对中括号[],表明数据类型为列表,列表中的每个元素都是字符串。
将列表赋值给变量名someLetters,因此,列表名称为someLetters,列表内容为["a", "b", "c", "d", "e"]。

[]
第2行中列表+中括号([]),括号中既有数字也有冒号(:),表明要对列表进行切片。

:
利用切片取元素时,需要使用冒号,用于分隔切片开始的位置和切片终止的位置。

数字
切片要遵循“左闭右开”原则,就是取左边的数据,不取右边的数据,与数学中的区间类似[1, 3),取左不取右。

注意:切片与索引类似,也是从0开始,即第一个元素的索引为0。

例如,第2行中的someLetters[1:3],索引从0开始,这里就是取第2个元素到第4个元素。

又需要遵循“左闭右开”原则,则取第2个到第3个元素,输出['b', 'c']。

代码小结
当我们想要使用切片的时候,我们可以使用这样的格式

切片时,开始位置和结束位置的数字,还有三种填写情况。

  1. 只填写结束位置的数字;

  2. 只填写开始位置的数字;

  3. 两侧数字都不填写。


  4. 开始位置数字不填,默认从第一个元素开始切片。根据“左闭右开”原则,如图,从第一个元素(含)开始,取到第三个元素(含)。


  5. 结束位置数字不填,默认从开始位置切片,取到最后一个元素。

注意:不填写结束位置的数字时,列表中最后一个元素也会被提取。如图,表示从第二个元素(含)开始,到最后一个元素(含)结束。

  1. 开始位置和结束位置都不填写时,就是取列表中的所有元素。如图,[:]直接取出所有元素,但这种用法不常见,了解即可。

学习了列表的切片方法后,元组也可以使用切片来截取一段数据,如图所示。

学习了索引和切片访问列表中数据的方式后,如果,某个列表中的数据定义错误了,想要进行修改,该怎样操作呢?

列表的修改


friendName = ["Kevin", "Tony", "Asum"]
print(friendName)
print(friendName[0])
friendName[0] = "Jessica"
print(friendName)

# output

# ['Kevin', 'Tony', 'Asum']
# Kevin
# ['Jessica', 'Tony', 'Asum']

代码的作用
这5行代码定义了一个叫做“friendName”的列表,并输出了不同的结果。

第1行给列表friendName赋值了三个数据:Kevin,Tony,Asum
第2行输出整个列表。
第3行输出列表中的第一个数据,也就是字符串"Kevin"。
第4行通过代码friendName[0]修改了列表的第一个数据,给它赋值字符串"Jessica"
第5行输出了列表friendName

friendName
变量名,用来存储这个列表。

[ ]
一对中括号,用来表示一个列表。

[0]
中括号加数字,作为索引,用来定位列表中的某个数据。
本例中,索引0表示第一个数据。

Jessica
一个字符串,重新给friendName这个列表中的第一个数据赋值。

代码小结
当我们要对列表中的数据进行修改时,可以使用图中格式

列表和元组有很多相似点,但列表的修改不能应用于元组中,元组具有不可变的特性。
元组的内容定义完成后,里面的内容就不能修改

由于,元组是不可修改的,强行修改会出现以下 bug:
类型错误:
当对元组进行修改时,就会提示元组类型数据更改(TypeError: 'tuple' object does not support item assignment)

了解以上知识点后,我们需要对元组和列表进行区分:

相同点:

  1. 可以使用索引定位到某个元素;
  2. 可以使用切片取一个片段;
  3. 可以存储不同的数据,如,字符串、整型、浮点型、布尔数等。

不同点:元组内容是不可修改的。

例如:程序员在编写程序时,也会犯错,因此像元组这样不可变的数据结构可以有效防止写代码的人因为自己的错误,误修改了里面的数据。

列表的便捷操作

学习如何在列表中追加元素、插入元素和删除元素。

列表的追加

追加(Append):追加一般用于描述在列表的末尾添加元素的行为。

Python 提供了给列表追加元素的功能。
当我们想在列表的尾部追加一个元素的时候,可以在列表名后使用 append() 语句。


friendName = ["Max", "Jeremy", "Christina"]

friendName.append("Vane")

print(friendName)

代码的作用
这三行代码定义了一个名为 friendName 的列表,并给这个列表追加了一个元素,最后输出了这个列表。

列表名
friendName 是一个列表名,用来表示先前定义的列表。

句点
一个句点,表明将会使用列表的某个内置功能。
这是一个固定的搭配格式,只能使用英文句号,不能替换成其他符号。

append
append,类似print,表明我们要在这个列表的尾部添加新的元素。

( )
一对英文括号,这是 append 功能的固定格式。括号内是具体要添加到列表末尾的元素。

追加元素
在列表 friendName 中追加一个元素,使用 append() 一次只能追加一个元素。

使用 append() 可以追加不同数据类型,包括:字符串、整型、浮点型、元组以及列表等。
在第 4 行代码中,虽然追加的是列表,但是也看作一个元素

代码小结
当在列表尾部追加一个数据时,使用如下格式:

列表的插入

在 Python 中,可以使用 insert() 语句来执行插入元素的操作。


rank = ["Max", "Jeremy", "Christina"]

rank.insert(1,"May")

print(rank)

代码的作用
在这段代码中,定义了一个名为 rank 的列表,在这个列表中间插入了一个字符串"May",并在最后输出了这个列表。

列表名
rank 是一个列表名,用来表示先前定义的列表。

句点
句点,表明将会使用列表的某个内置功能。

insert
insert,类似print。表明我们要在这个列表的某个位置插入新的元素。

( )
一对括号,这是insert功能的固定格式。括号内是插入的元素位置以及要插入的元素。

两项内容
我们需要在 insert() 的括号中填入两项内容:
第一项是元素插入的位置;
第二项是插入的具体数据。

索引
第一个数字位置表示索引,也就是这个元素要插入到列表中的位置。
索引是从 0 开始。
本例中索引 1 表示插入到第二的位置。

逗号
一个逗号,用来分隔插入的位置以及插入的具体数据。

插入元素
插入的元素可以是不同数据类型,包括:字符串、整型、浮点型、元组以及列表等。
在本例中,我们向列表中插入一个字符串"May"。

插入元素以后,排在此元素之后的原有元素自动后移一位。
在本例中,"May"插入到列表rank中的第二项中,原有的"Jeremy"和"Christina"就自动后移一位。

代码小结
当在列表中插入一个数据时,使用如下格式:

列表删除元素

学习的两个列表内置语句:append() insert(),这两个语句都可以往列表中添加新元素。
如果列表中存在不需要的元素,想要删除它,可以使用 pop(),删除列表中的元素。


primeNumber = [1, 3, 5, 7, 9, 10]

primeNumber.pop()

print(primeNumber)

代码的作用
这段代码定义了一个名为 primeNumber的列表,并且删除了这个列表中最末尾的一个元素,最后输出了这个列表。

列表名
primeNumber 是一个列表名,用来表示先前定义的列表。

句点
一个句点,表明将会使用列表的某个内置功能。

pop( )
pop(),作用是删除列表中指定索引处的元素。
括号内的数字表示要删除数据的索引,不填写数字则表示默认删除列表中的最后一个数据

pop() 括号内的数字表示要删除数据的索引,在本例中索引值为1,就删除了列表primeNumber中的第二项元素。

代码小结
当我们需要从列表中删除一个数据,使用如下格式:

pop()在删除列表指定的元素后,可以赋值给变量存储下来。
本例中,删除的是列表primeNumber中最后一项元素 10,将整型 10 赋值给变量lastData,接着通过print()输出变量lastData。

我们前面的例子在定义一个列表时,都是使用的常量来作为列表中的元素。
变量也同样可以作为定义列表的元素,并且列表的各种操作也同样适用于变量数据。
图例中展示了变量作为列表元素时,代码的使用方式。

数据结构

之前学习的变量可以存储1个数据,当我需要存储10个数据的时候怎么办呢?
写10个变量可以解决这个问题,但是太冗长。

也可以如图所示,用这样一个变量来存储10个数据。
在Python中,有几种内置的“容器”,可以按不同的方式存储多个数据的集合。

这样的“容器”,称之为“数据结构”。

数据结构是计算机存储和组织数据的方式。

数据结构有很多种,其中使用最多的,是元组(tuple)、列表(list)、字典(dict)这三种。

储存多个数据的元组

假设我们想要存储日期的数据,将“1月1日”,“1月2日”,“1月3日”,“1月4日”存储在一起,这时就可以使用元组(tuple)。

元组,是一种由多个数据组成的有序数据集合。它就像一排抽屉,我们可以在抽屉里面放不同的东西。

“1月1日”,“1月2日”,“1月3日”,“1月4日”使用元组存储在一起,可以写成如图的样子。

来具体学习元组的代码写法。


calendar = ("1月1日", "1月2日", "1月3日", "1月4日")
print(calendar)

代码的作用
这2行代码定义了一个calendar的元组,然后打印了这个元组。

第1行给一个元组赋值了"1月1日", "1月2日", "1月3日", "1月4日"这四个日期;

第2行打印了calendar这整个元组。

( )
一个括号,是定义元组的固定格式。

元组的变量名
这串字母calendar是元组的变量名。

四个字符串
四个字符串,这里的四个字符串数据是元组包含的四个元素。

,
三个逗号,逗号是用来分隔元组里面各个元素的固定符号。
逗号右边的空格可有可无,这里添加空格是为了代码风格考虑。

代码小结
当我们想要使用元组的时候,可以使用这样的格式

元组里可以存储各种各样的数据类型,一个元组可以完全由整型、浮点型、字符串、布尔数构成。
也可以由这几种数据类型的常量混合组成。

元组中的数据是有顺序的。也就是说,如图在calendar这个元组里面,排在第一位的是"1月1日",第二位是"1月2日",第三位的是"1月3日"。第四位的是"1月4日"。

当我们输出calendar[0]的时候,就得到了这个元组的第一个数据。像这样访问它内部数据的机制,叫做“索引”。

索引

索引是在数据结构中用来定位和寻找数据的检索方式。

可以通俗理解为索引是数据的位置。
索引都是从0开始的。因此,第一个数据的索引为0,第二个数据的索引为1,以此类推。

可以通过中括号[]和索引的方式,直接访问到某一个位置的元素。
如图,通过索引,直接输出了第一个元素和第二个元素。

倘若一个元组的元素非常多,我们想要寻找某一个数据,是不是在元组中,用肉眼看的方式非常麻烦。
元组这样的数据结构,有一种运算方式,叫in运算符,可以进行快速判断。

in运算


numbers = (0,1,2,3,5,8,13,21,34,55,89,144,233,377)
result = 5 in numbers
print(result)

代码的作用
这3行操作,判断了5是否是元组中的一个元素。
第1行,定义了一个元组numbers。
第2行,进行一次in运算,判断5是否是元组numbers中的一个元素,将运算结果赋值给result
第3行,输出运算结果是True

常量
判断这个数据,是否是元组中的一个元素。

元组
需要判断的5,是否是这个元组中的一个元素。

in运算符
in运算,进行5 是否是 numbers 中的元素的运算。

result
将in运算后的结果赋值给变量result,然后进行输出。

in运算的结果,是一个布尔值(True/False)。

代码小结
当我们要输出一段完整文字就需要这几个部分

判断语句

判断语句是程序的三大语句结构之一。

它的作用是根据判断的条件是否成立(真或假),来决定后续代码执行顺序。

单选选择的判断-if判断


yourAge =  20
myAge = 18

if yourAge > myAge:    
    print("你的年龄比我大")

代码的作用
这段代码将两个人的年龄进行判断,并且输出了结论。
第1行和第2行代码,将年龄分别赋值给两个变量。
第4行代码将两个变量进行判断。
第5行代码,输出"你的年龄比我大"。

if
使用 if (中文翻译为如果),表明我们要在这里进行语句判断。

判断条件
if 后的判断条件通常是一个布尔表达式。
即该表达式有两种结果:True False
本例中,yourAge > myAge 的运算结果为 True

冒号
判断语句的固定格式,用来表示这行判断条件的结束。

四个空格
用四个空格标记当 if 判断条件为True(真)时,需要执行的语句。
在这里,先记住这个格式,稍后会讲解这里空四格的原因。

执行部分
if 判断条件为True(真)时,程序就会执行if 判断内的代码。
在这里我们使用 print() 语句输出"你的年龄比我大"。

执行顺序
if 判断的执行顺序,梳理成流程图后,再来整理一下运行流程。
第一种情况,程序运行到 if 判断时,如果条件为真,则进入执行部分;完成后,程序接着运行 if 判断下面的代码。

第二种情况,程序运行到 if 判断时,如果条件为假,程序就直接跳开 if 判断的执行部分,运行后面的代码。

代码小结
通过以下格式在代码中使用 if 判断语句

关键字

关键字是程序语言中有特殊意义的单词,它们都不能被用来作为变量名,函数名,类名等。

此外,由于变量名区分大小写,所以 if 不能作为变量名,但 IF 、If、iF可以。

缩进

Python 中不同层级的代码之间强制要求缩进,并且相同层级的代码要求缩进的空格数量一致。

在这里第 1 到 3 行代码属于同一层级,第 4 和第 5 行代码属于同一层级。

在Python中,缩进的数量不做强制的要求,可以 1 个空格,可以 2 个空格
建议每个缩进用 4 个空格,这是一种比较美观易读的代码风格。

代码块

同一层级的代码集合叫做代码块,代码块中的代码会按由上至下的顺序执行。
在 Python 中,通过缩进来划分代码块。
if 判断后面跟随条件,如果条件成立,程序执行归属于 if 判断的一个代码块。
这时候就需要使用缩进组织代码块,区分代码的层级。

在连续的多个 if 判断中,每一个 if 判断内都有一个代码块。
只有当 if 条件成立时,程序才会执行这个 if 判断里面的代码块。
如果条件不成立,程序就会跳开这个 if 判断,继续运行接下来的代码。

多个if判断
例如:Tony的年龄是12岁,Kevin的年龄是11岁。判断谁的年龄更大,然后输出他的名字。

我们需要考虑两种情况:

  1. 如果 Tony 比 Kevin 大,输出 Tony 的名字;
  2. 如果 Tony 比 Kevin 小,输出 Kevin 的名字。

在这里,连续使用两个 if 判断就可以得到结果,编写出来的代码如图所示。

有了判断语句,我们就可以打破代码的默认执行顺序了(按由上至下的顺序执行)。
如图,两段代码里都有一行代码是不会执行的。
判断语句“里面”的代码块只有当判断布尔表达式为真的时候才会执行。

if 判断时,最容易出现以下两种 bug:

  1. 缩进问题
    同一代码块缩进需要保持一致,建议每个缩进用 4 个空格。


  2. 语法错误
    if 判断中,布尔表达式后面的冒号常常被遗漏,这是判断语句的固定格式。


学习了 if 判断,如果布尔表达式成立,就执行后面的代码块。
假设,if 判断后面的布尔表达式不成立,我们想要执行另外的代码块,这该怎么办呢?

在图例中,我们使用了两个 if,来保证对比情况都会有对应的输出。
为了更便捷地写出代码,我们可以使用 if-else 来优化这段程序。

if 后面的语句是当判断条件成立时,需要执行的操作。
else 后面的语句是判断条件不成立时,执行的操作。

双选选择的判断-if-else


yourScore = 80
myScore = 90

if yourScore > myScore:
    print("你的得分比我高")
else:
    print("你的得分不比我高")

代码的作用
本例中比较了变量 yourScore 和变量 myScore。
如果 yourScore 大于 myScore,就输出"你的得分比我高"。
第7行代码进行 else 判断,否则就输出"你的得分不比我高"。

if 判断
if 后面的布尔表达式,在这里不成立。
if 里面的代码块,也就是第5行代码,不会被执行。

else
一个关键字 else,如果之前的 if 判断条件不成立,就执行 else 的代码块。

冒号
在 else 之后使用冒号,表示后续缩进的代码块在判断条件不成立的时候会被执行。

缩进
缩进生成 else 内的代码块,这里我们还是空四格。

执行顺序
把 if-else 语句的执行顺序,梳理成流程图后,再来整理一下程序运行流程。

第一种情况,程序运行到 if 判断时,如果条件为真,执行 if 的代码块。
完成后,运行 if-else 后面的代码。

第二种情况,程序运行到 if 判断时,如果条件为假,程序就直接跳开 if 判断的执行部分,运行 else 的代码块。
完成后,运行 if-else 后面的代码。

代码小结
使用if-else的格式

if-else 语句有两个特性。
第一,else 需与 if 搭配使用,它无法独立出现。
必须先有 if,然后才能使用 else,否则程序就会报错。

第二,if 与 else 成互斥关系。
互斥关系也就是说,程序不会既执行 if 内的代码块,又执行 else 内的代码块。
else 是把 if 判断条件无法囊括的情况全部揽到了自己这里。

学习了两种判断语句 if 和 if-else。

if 语句属于单向判断。
只要条件成立,就会运行 if 内的代码块;条件不成立,程序就会跳开 if 判断。

if-else语句属于双向判断。
如果 if 的条件不成立,就执行 else 内的代码块。
if 和 else 是两个互斥关系,程序只会执行其中的一个。

当我们在同时使用 if 和 if-else 语句时,要注意 if 和 else 的关系。
例如,图例中的代码,包含了 2 个 if 判断和 1 个 if-else语句,这三个判断互不影响。
在这里,else 是与第 3 个 if 搭配成 if-else 语句,与前两个 if 无关

在判断语句中,除了使用布尔表达式可以作为条件,还有其他的数据类型也可以作为判断条件。
图中代码能够正常运行是因为 myAge 被赋值了一个整型 20,所以它被判定为 True,于是程序继续执行了下一步代码。

在这里,变量myAge就是“非零非空”数据

“非零”这个概念比较好理解,数字 0 被判断为False,其他数字(包含正数和负数)都被判断为True。
“非空”是什么意思呢?要理解“非空”先要理解“空值”这个概念。

空值

空值,又叫 NULL 值,在 Python 中写作 NoneNone 是关键字。
它代表这个数值不是整型,不是字符串,不是浮点型,表示没有值。
注意,它和 0 不一样,因为 0 的值是 0,而空值的值是None。

了解了“空值”后,“非空”就更好理解了。
当一个变量里有值,并且这个值不是空值,我们就说这个变量非空。
非空值可以是整型、字符串、浮点型和布尔数。

非值

当一个变量里有值,并且这个值不是空值(None),我们就说这个变量“非空”。
同时我们也把所有不是空值的值称为“非空值”。

布尔表达式和非零非空数据,都可以作为判断语句的条件。
在判断语句中,对非零值判断为真;对数字0的判断为假;对 None 的判断为假。

接触 if-else 判断时,最容易出现以下两种 bug:

  1. 语法错误
    else 后面的冒号常常被遗漏,这是if-else的固定格式,有冒号程序才知道下面是 else 的代码块。

  2. 缩进问题
    if 和 else 为互斥关系,else 的代码块需要通过缩进形成。为了保持风格统一,每个缩进用 4 个空格。


复杂的多项选择 - elif

但是生活中,N 选一的情况更为多见。
在Python中,也可以通过添加更多的选择,实现从“二选一”到“多选一”的进阶

如图所示,为了实现完整的判断,我们使用了三个 if,来保证所有的得分对比情况(大于、等于、小于)都会有对应的输出。

但是对于这种3个或以上的条件,无法使用一个if-else 结构来优化代码。
这时可以使用Python判断语句中的第三个关键字 elif(else if的缩写)。

if 后的语句是当 if 判断条件成立时,执行的操作。
elif 后的语句是当 if 判断不成立时,再判断一次,如果成立,执行的操作。
else 后的语句是当以上所有判断条件都不成立时,执行的操作。

elif


day = 3

if day == 1:
    print("元气满满地工作")
elif (day >= 2) and (day <= 5):
    print("继续搬砖吧")
else: 
    print("世界这么大,出去走走吧")

代码的作用
本例第3、4行代码判断了如果变量 day 等于1,就输出"元气满满地工作"。
第5、6行代码判断了如果变量 day 大于等于2并且小于等于5,就输出"继续搬砖吧"。
第7、8行代码判断了如果之前的条件都不满足,就输出"世界这么大,出去走走吧"。

if 判断
if 后面的布尔表达式,在这里不成立。
if 里面的代码块,也就是第4行代码,不会被执行。

elif
一个关键字,是 else 和 if 的缩写。
如果之前的 if 判断条件不成立,就再做一次新的判断,执行 elif 后面的代码。

布尔表达式
两次比较运算,如果变量 day 大于等于2,如果变量 day 小于等于5。
本例中结果都为 True 。

一次逻辑运算 and(“与”运算)。
本例中参与运算的分别是 True 和 True ,运算结果为 True 。

括号,用来框定代码运算的顺序,表明先进行比较运算,再进行逻辑“与”运算。

冒号
就像 if 和 else 一样,elif 语句的最后也需要一个冒号。
在 elif 之后使用冒号,表示后续缩进的代码块在判断条件成立的时候会被执行。

缩进
缩进生成 elif 内的代码块,这里还是空四格。

else
一个关键字 else,如果前面的 if 和 elif 的判断条件都不成立,就执行 else 后面缩进的代码块。

执行顺序
把 if-elif-else 判断的执行顺序,梳理成流程图后,再来整理一下程序运行流程。

第一种情况,程序运行到 if 判断时,如果条件为真,执行 if 的代码块。
完成后,运行 if-elif-else 后面的代码。

第二种情况,程序运行到 if 判断时,如果条件为假,程序就直接跳开 if 判断的执行部分,再次运行到 elif 的判断,如果条件为真,执行 elif 的代码块。
完成后,运行 if-elif-else 后面的代码。

第三种情况,程序运行到 elif 判断时,如果条件为假,程序就直接跳开 elif 判断的执行部分,运行 else 的代码块。
完成后,运行 if-elif-else 后面的代码。

代码小结
通过 elif 进行条件判断时,我们可以使用这样的格式

if-elif-else 语句有3个特性。

  1. 如果不满足 if 的条件,就判断是否满足 elif 的条件,满足就执行 elif 内的代码块,不满足就执行 else 内的代码块。

  2. elif 需与 if 搭配使用,它无法独立出现。必须先有 if ,然后才能使用 elif ,否则程序就会报错。


  3. if 、elif 与 else 成互斥关系。
    互斥关系指的是,程序不会同时执行 if 内、 elif 内和 else 内的代码块,只会执行其中一个。
    else 是把 if 和 elif 判断条件无法囊括的情况全部划分到自己这里。


现在,已经学习了三种判断语句:
if if-elseif-elif-else

通过 if 、else 、elif 的搭配使用,我们可以覆盖条件判断中的所有情况,让程序按照我们预定的逻辑来执行很多自动化的工作。

if 语句属于单向判断。
只要条件成立,就会运行 if 内的代码块;条件不成立,程序就会跳开 if 判断。

if-else 语句属于双向判断。
如果 if 的条件不成立,就执行 else 内的代码块。
if 和 else 是两个互斥关系,程序只会执行其中的一个。

if-elif-else 语句属于多向判断(3个或以上的条件)。
如果 if 的条件不成立,就执行 elif 再判断一次,如果 elif 的条件也不成立,就执行 else 内的代码块。
if 、elif 、 else 是互斥关系,程序只会执行其中的一个。
并且,当判断的条件超过3个时,中间的多个条件都可以使用 elif,无论中间有多少个 elif ,它和其他 if 、elif 都是互斥关系。

嵌套语句

嵌套语句在很多地方都有应用,这里主要了解 if 的嵌套。

if 嵌套:
在基础条件满足的情况下,再在基础条件里面增加额外的判断条件,即条件里套条件。

if嵌套


time = 13
num = 2

if (time >= 9) and (time <= 23):
    print("在打折时间内")

    if num >= 2:
        print("全场八折")

代码的作用
本例第1、2行代码分别将时间13和数量2赋值给了变量 time 和 num 。
第4、5行代码判断了如果变量 time 大于等于9并且小于等于23,就输出"在打折时间内"。
第7、8行代码在变量 time 大于等于9并且小于等于23成立的条件下,判断了如果变量 num 大于等于2,就输出"全场八折"。

外层条件
第一层判断条件 if 。
首先判断了如果变量 time 大于等于9并且小于等于23,就输出"在打折时间内"。

内层条件
第二层判断条件 if 。
在第一层判断变量 time 大于等于9并且小于等于23成立的条件下,判断了如果变量 num 大于等于2,就输出"全场八折"。

缩进四格
Python是以缩进的空格数来区分代码块的。
如果外层条件和内层条件的代码块都采用同样的缩进,Python 就没办法区分内外层条件是如何嵌套的。
在这里,外层条件 if 语句内的代码块缩进四个空格

缩进八格
在将内层条件 if 语句写进外层条件的执行分支时,内层条件 if语句内的代码块要在原有缩进的基础上,再增加相应的缩进。
在这里,内层条件 if 语句内的代码块在外层条件内的代码块缩进的基础上再加四个空格,也就是八个空格。

注意⚠️ :缩进在Python语法规则中扮演重要的角色

执行顺序
把 if 嵌套的执行顺序,梳理成流程图后,再来整理一下程序运行流程。
如图所示,嵌套的原则是先确定外层条件再确定内层条件,只有当外层条件成立时,才有可能进入到内层条件当中继续执行。

需要注意的是,在相互嵌套时,一定要严格遵守不同级别代码块的缩进规范。
每嵌套一层都需要在原有缩进的基础上,再增加相应的缩进。

代码小结
当要使用 if 嵌套时,就可以用这样的格式

不仅是 if 嵌套 ,在Python中,if 、if-else 和 if -elif-else 之间也可以相互嵌套。
嵌套原则与 if 嵌套类似。

如图所示,这是一段能实现分组和判断成绩的代码。
1个外层条件 if-else 语句判断变量 gender 的值,确定男女分组,2个内层条件 if-else 语句判断变量 score 的值,确定成绩情况。

值得注意的是,虽然使用嵌套可以大大提高代码的逻辑性和层次感。
但是,任何东西都不能过度使用。
一般来说,超过3层以上的嵌套会使代码变得难以阅读,不符合Python简洁表达的理念。