阅读量

原创教程,严禁转载。引用本文,请署名 Python中文网, http://www.zglg.work


Day16 列表和循环

这一周,我将介绍一种称为“列表”的新数据类型和一种称为“循环”的新概念。列表将让我们有能力存储大规模的数据,而循环将可以让我们有能力反复执行特定部分的代码。

由于列表天然适合循环,因此,我们这周将这两个主题一起讲解。列表作为Python中最重要的数据类型之一,在正试讲解之前,我们需要理解数据类型的基础和分支语句。在这周末,我们将使用编译器来构建一个小规模的hangman游戏。在这个游戏的构建中,我们将会用到之前几周和本周所学到的知识和概念。

通过将所学到的知识和概念不断应用到实践中,这将有助于你更深入的理解这些知识和概念。如果你还没有一个概念,重要的是要继续努力,并尽量避免陷入单节课。

本章概览

理解列表类型

如何使用循环并理解背后原因

理解列表如何运作

一起创建Hangman

问题

想象你是一个大城市的市长,而这一城市我们假定为波士顿。你已经收到灾难预警,需要疏散城市市民。你首要做的是什么事呢?

星期一:列表

今天,我们将介绍Python中最重的数据类型——列表。在其它的编程语言中,它们也被称之为“arrays”并有类似特征的数据类型。这将是你所学到的第一个数据集合。在之后的几周中,我们将了解和学习其它的数据集合。

为了更好的学习今天的内容,让我们打开“python_bootcamp”文件夹中的Jupyter Notebook,创建一个新的文件,并命名为“Week_04”。接下来,创建一个有着列表标题的Markdown代码块。从这里,我们将开始学习代码块下的列表类型。

什么是列表?

列表是Python中的一种数据结构,这一数据结构中的元素是可迭代的、有序的。可迭代意味着当有序元素涉及到位置索引时,你能够改变对象内部。在一个列表中的第一个元素将一直为索引0。对象是指列表内部的每一个元素或值。正如字符串被所引用的字符所定义一样,列表则通过英文状态下的方括号([])中不同的数据类型所定义。同时,由于对象存储在电脑内存中,和字符串一样,列表中的每一个对象都会分配一个索引或位置。因此,列表也是一个数据集合。数据集合是能够储存多个对象的数据类型。我们在之后的几章中将会看到字典和元组等其它数据集合。

创建一个包含多个数字的列表

对于我们第一个列表,我们将创建一个只包含数字的列表。列表的定义与其他数据类型定义相似,左边是变量的名称,右边是数值。所不同的是数值是处于方括号中的一系列对象。这对于存储类似信息时非常有用,因为你可以很容易通过一个变量名而存储多个元素。我们使用commas来分隔列表中的每一个对象。接下来,让我们动手试试:

# 创建一个包含多个数字的列表
nums = [5, 10, 15.2, 20]
print(nums)

继续并且运行这一代码块。你将得到一个[5, 10, 15.2, 20]的输出结果。当列表输出结果时,方括号也会一同输出。从输出结果中可以看到,这个列表由三个整数和一个浮点数组成。

获取列表中的元素

现在我们知道如何定义一个列表,那么,接下来,我们需要知道怎样来获取列表中的元素。为了获取列表中的特定元素,我们需要用到索引。当我们声明一个列表变量时,每个对象都被赋予一个索引。我们需要牢记:Python中的索引是从0开始,使用索引需要用方括号。之前,在第2周的星期三,我们也用到过索引。如果忘记的话可以翻到前面温习下哦!

# 获取列表中的元素
print(nums[1]) # 将输出索引1(即列表中第2个元素)位置上的值10 
num = nums[2] # 将索引2(即列表中的第3个元素)位置上的值15.2赋予给变量num
print(num) # 输出分配为变量num的值

继续并运行这一代码块。我们将得到数字10和15.2两个值的输出。第一个值输出是因为我们提取列表nums中索引位置1上的元素,这一位置上存储的是整数10。我们创建了一个新变量num后,第二个数据被打印出来。因为num变量存储了列表nums中索引位置2上的元素。

创建一个混合数据类型的列表

列表能创存储任意数据类型,甚至是列表本身。让我们来看下其它数据类型的例子。

# 创建一个混合数据类型的列表
num = 4.3
data = [num, “word”, True]  # 多个数据类型的数据集合
print(data)

继续并运行这一代码块。它将会输出[4.3, “word”, True]。它会输出4.3作为第一个对象,因为定义列表时,它存储了变量num的数值,而非变量自身。

包含列表的列表

让我们创建一个更复杂并且看列表是如何存储另一个列表:

# 理解包含列表的一个列表
data = [5, “book”, [34, “hello”], True]  # 列表能包含任何类型
print(data)
print(data[2])

继续并运行这一代码块。它将会输出[5, “book”, [34, “hello”], True]和[34, “hello”]。第一个输出是变量data中的所有元素,包括整数、字符串、列表和布尔数据类型。第二个输出存储在变量data中的列表,它位于列表data索引位置2上的子列表,这一子列表中包括整数和字符串数据类型。

获取列表中的子列表

在最后这一代码块中,我们看到如何输出存储在变量data中的列表。现在,我们来学习如何获取子列表中的对象。通常来说,为了获取列表中的对象,我们仅用方括号和索引的位置即可。而当对象在别一个列表中时,你仅需要在第一个set之后再增加一个set即可。让我们来看一个实例并试着理解它:

# 使用两个方括号去获取列表中子列表的对象
print(data[2][0])  # 输出34
inner_list = data[2] # 变量inner_list将被赋值[34, ‘hello’]
print(inner_list[1])

继续并运行这一代码块。第一个输出的结果是34。这是因为我们获取了变量data中索引位置为1(即变量中第2个对象)的对象,即子列表。继而获取了子列表中索引位置为0(即子列表中的第1个对象)的元素34。第二个输出结果是“hello”。因为我们创建了一个变量来存储变量data中索引位置2(即变量data中第2个对象)上的对象。而这一索引位置上正是变量data中的子列表。接下来,我们将[34, ‘hello’]赋与所创建的变量inner_list。我们获取这个列表中索引位置为1(即列表中的第2个对象)的对象。为了更好的理解多个索引如何发挥作用,让我们来看表4-1。

表4-1 多索引值

索引位置 位置上的值 数据类型 是否包含子列表索引
0 5 整数Integer NO
1 “book” 字符串String YES
2 [34, “hello”] 列表List YES
3 True 布尔值Boolean NO

我们要注意字符串也是带有索引的数据类型。比如你仅仅想打印出字符串”book”中的字母b,你只需要这样写代码:

print(data[1][0])  # 输出”b”

更改列表中的数值

更改列表中的数值可以更好的让你利用列表来处理数据。更改列表中的值就像重新创建一个包含不同值的普通变量,唯一不同的是你需要获取值的索引,如下图所示:

# 通过索引更改列表中的数值
data = [5, 10, 15, 20]
print(data)
data[0] = 100 # 更改索引位置0(列表中第1个元素)上的数据
print(data)

继续并运行这一代码块。在我们更改索引位置0上的数据之前,列表输出结果为[5, 10, 15, 20]。而当我们将索引位置0上的数据更改为100时,列表的输出结果变为[100, 10, 15, 20]。

变量存储

当变量被创建后,变量中的数据就会分配到内存中的特下位置。这些位置都有一个特殊的ID。一般来说,我们不会经常检查一个变量的ID,但是为了更好的说明列表如何进行存储工作,我们将使用id()函数来展示出变量在内存中的特定位置。

a = [5, 10]
print(id(a))  # 很大的一串数代表了变是在内存中的位置

当一个列表存储在了内存中,列表中的每一个对象也被给予了自己的位置。使用索引改变数值将会改变存储在内存模块的值。现在,如果一个变量的值被赋给别一个变量,像这样:

a = [5, 10]
b = a

在特定的索引位置上改变数值将会同时改变等于该变量的新的变量中的数值。让我们来看这样一个例子:

# 理解列表如何被存储
a = [5, 10]
b =a
print(“a:{}\t b:{}”.format(a, b))
print(“location a[0]:{}\t Location b[0]:{}”.format(id(a[0]), id(b[0]))
a[0] = 20
print(“a:{}\t b:{}”.format(a, b))

继续并运行这一代码块,我们将获取一些输出结果。第一个输出的值是两个列表a和b中的所有的值,这些值都是一样的。第二个输出的值是列表中第一个对象在内存中的位置。而最后,在我们改变列表A中的第一个对象的值后,列表B中对应第一个对象同样被改变。这是因为它们使用了相同的内存位置。

复制一个列表

问题来了,你如何在不改变原始列表的情况下创建一个类似的列表?复制它们就可以了。让我们来看下如何操作:

# 使用[:]复制一个列表
data = [5, 10, 15, 20]
data_copy = data[:]  # 仅复制了列表
data[0] = 50
print(“data:{}\t data_copy:{}”.format(data, data_copy))

继续并运行这一代码块。这次输出的结果是第一个对象已经变为50的变量data。由于data_copy仅仅对列表进行了复制,现在我们能够一直保留原始列表数据。如果我们需要使用它,我们要以随时调用。


注意:你也可以使用.copy()方法。


练习

  1. 运动:定义一个包含各种运动名字的列表。并用“I like a play {}”语句来输出包含每一个运动的名字的句子……
  2. 第一个字母:对于下面的列表,列印出每一个对象的第一个字母(输出应该是”J”,”A”,”S”,”K”)

$$ names = [“John”, “Abraham”, “Sam”, “Kelly”] $$


小提示:利用列表的索引值进行元素提取。


今天是我们第一个数据集合——列表的所有要点。它保含了很多知识点,但是最重要的是理解如何定义,修改值和复制列表。

上一篇:Day15
下一篇:Day17