首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

有趣的Python列表和字典

The best way to learn a programming language is to write a lot of code and read a lot of code.

我们已经见过Python可以在内存中存储信息,还可以用名字来获取原先存储的信息。到目前为止,我们存储过字符串和数(包括整数和浮点数)。有时候可以把一堆东西存储在一起,放在某种“组”或者“集合”中,这可能很有用。这样一来,就可以一次对整个集合做某些处理,也能更容易地记录一组东西。有一类集合叫做列表(list),另一类叫做字典(dictionary)。

列表非常有用,很多很多程序里都用到了列表。后面几篇开始讨论图形和游戏编程时,我们的例子中就会大量使用列表,因为游戏中的很多图形对象通常都存储在列表中。

那什么是列表呢

如果我让你建一个家庭成员列表,你可能会像下图这样写:

在Python中,就要写成:

family = ['Mom','Dad','Junior','Baby']

如果我让你写下你的幸运数字,你可能会这样写:

在Python中,就要写成:

luckyNumbers = [2,7,14,26,30]

family和luckyNumbers都是Python列表的例子,列表中的单个元素就叫做项或者元素(item)。可以看到,Python中的列表与你在日常生活中建立的列表并没有太大差异。列表使用中括号来指出从哪里开始,到哪里结束。

另外用逗号分隔列表内的各项,列表中的各项可以包含Python能存储的任何类型的数据,这包括数字、字符串、对象,甚至可以包含其他列表。并不要求列表中的元素是同种类型或同一种东西。这说明,一个列表中可以同时包含不同类型,例如数字和字符串,可能像这样:

my_list = [5, 10, 23.76, 'Hello', myTeacher, 7, another_list]

如何创建列表?

family和luckyNumbers都是变量。前面曾经说过,可以为变量赋不同类型的值。我们已经为变量赋过数和字符串,还可以为变量赋一个列表。

就像创建任何其他变量一样,创建列表也是要为它赋某个值,如前面对luckyNumbers的赋值。另外还可以创建一个空的列表,如下:

newList = [ ]

中括号没有任何元素,所以这个列表是空的。不过一个空列表有什么用呢?为什么想要创建这样一个空列表呢?

在很多情况下,我们无法提前知道列表中会有些什么。我们不知道其中会有多少元素,也不知道这些元素是什么,只知道将会用一个列表来保存这些内容。有了空列表后,程序就可以向这个列表中增加元素。

如何向列表增加元素?

要向列表增加元素,需要使用append()。在交互模式中试试下面的代码:

你会得到这样的结果:

再来增加一个元素:

记住,向列表增加元素之前,必须先创建列表(可以是空列表,也可以非空)。

我们仔细观察,还会发现friends和append()之间加了一个点(.)。实际上,这就是对象。

Python中的很多东西都是对象(object)。要想用对象做某种处理,需要这个对象的名字(变量名),然后是一个点(.),再后面是要对对象做的操作。 所以要向friends列表追加一个元素,就要写成:

friends.append(something)

我们会在后面篇章中学习关于对象的更多内容,不过现在先简单解释一下。

如何从列表获取元素?

取单个元素

下面用一些简单的内容建立一个新列表,这样我们在学习列表时就能更容易地了解做了些什么。在交互模式中键入下面的代码:

可以按元素的索引号从列表获取单个元素。列表索引从0开始,所以这个列表中的第一项就是letters[0],如下:

再来试一个:

我们发现,当我们索引letters[5]时并不是列表中的第5项,其实你要习惯从0开始索引,也就是说,当排在Python列表第5位的元素,它的索引就是4,因为Python列表的索引从0开始!

取多个元素-列表分片

我们还可以使用索引从列表一次获取多个元素,这叫做列表分片(slicing)。如上例子,在交互模式中键入下面代码:

这与for循环中的range()类似,分片获取元素时,会从第1个索引开始,不过到达第2个索引之前停止。正是因为这个原因,前面的例子中我们只取回3项,而不是4项。要记住这一点,一种方法就是牢记取回的项数总是两个索引数之差(4-1=3,所以取回3项)。

还有一个重要的问题需要记住:列表分片是原列表的部分副本。也就是说,对列表分片时取回的是另一个(通常更小的)列表,称为原列表的一个分片,而原来的列表并没有改变。

我们举个例子看这有什么不同:

对于第一种情况,我们取回一个元素。在第二种情况下,取回的是包含这个元素的一个列表。这个差别很微妙,但是你必须知道。即,在第一种情况下,我们使用了一个索引从列表得到一个元素。第二种情况下则是使用分片记法来得到列表的一个单元素分片列表(只包含一个元素的分片列表)。

要真正了解二者的区别,可以试试这些命令:

这里分别显示了两个结果的类型(type),从中可以清楚地看出,前一种情况下得到了一个元素(这里是一个字符串),后一种情况下得到的是一个列表(list)。

对列表分片时会得到一个较小的列表,这是原列表中元素的一个副本。这说明,可以修改这个分片列表,而原列表不会受到任何影响。

分片的简写

如果你想要的分片列表包括列表的开始部分,简写方式是使用冒号,后面是想要的元素个数,例如:

注意,冒号前面没有数字。这样就会得到从列表起始位置开始一直到(但不包括)指定索引之间的所有元素。

如果你想得到列表末尾也可以用类似的记法,如下:

使用一个后面跟冒号的数,这样可以得到从指定索引到列表末尾的所有元素。

如果你想得到整个列表,也就建立原列表的副本,你可以用以下记法:

letters[:]会建立整个列表的副本赋给new_list。如果你想对列表做些修改,但是同时还想保持原来的列表不做任何改变,使用这种分片就会很方便。可以看看下面的例子:

如何修改列表中的元素?

可以使用索引来修改某个列表元素:

但是不能使用索引向列表增加新的元素。目前,这个列表有5项,索引分别是从0到4。所以不能这样做:

这是不行的,这就像是想要改变一个还不存在的东西。

向列表增加元素的其他方法

我们已经看到了如何使用append()向列表增加元素。实际上,向列表增加元素共有3种方法:append()、extend()和insert()。

append()向列表末尾增加一个元素。

extend()向列表末尾增加多个元素。

insert()在列表中的某个位置增加一个元素,不一定非得在列表末尾。你可以告诉它要在哪里增加元素。

增加到列表末尾:append()

我们已经见过append()是如何工作的。它把一个元素增加到列表末尾:

再来增加一项:

注意这些字母并没有按顺序排列。这是因为append()只是将元素增加到列表的末尾。如果希望这些元素按顺序排列,必须对它们排序。稍后就会谈到排序。

扩展列表:extend()

extend()在列表末尾增加多个元素:

注意extend()方法的圆括号中的是一个列表。列表有一个中括号,所以对于extend(),可以同时有圆括号和中括号。

提供给extend()的列表中的所有内容都会增加到原列表的末尾。

插入一个元素:insert()

insert()会在列表中的某个位置增加一个元素。可以指定希望将元素增加到列表的哪个位置:

在这里,我们将字母z增加到索引为2的位置。索引2是列表中的第3个位置(因为索引从0开始)。原先位于第3个位置上的字母(也就是c)会向后推一个位置,移到第4个位置上。它后面的每一个元素也都要向后移一个位置。

append()和extend()的区别

有时append()和extend()看起来很类似,不过它们确实有一些区别。下面再加到原来的列表。首先,用extend()增加3个元素:

现在,再用append()做同样的事情:

我们可以看到,append()会向列表增加一个元素。它并没有增加3个元素,这里确实只是增加了一个元素,只不过这个元素刚好是一个包含3项的列表。所以在这个列表中多了一对中括号。要记住,列表可以包含任何东西,也包括其他列表。这个例子就属于这种情况。

insert()的工作与append()相同,只不过你可以告诉它在哪里放入一个新的元素。而append()总是把新元素放在列表的末尾。

如何从列表删除元素?

从列表删除或者去除元素,有3种方法:remove()、del和pop()。

用remove()删除元素

remove()会从列表中删除你选择的元素,把它丢掉:

你不需要知道这个元素在列表中的具体位置,只需要知道它确实在列表中(可以是任何位置)。如果你想删除的东西根本不在列表中,就会得到错误消息:

用del删除

del允许利用索引从列表中删除元素,如下所示:

在这里,我们删除了第4个元素(索引3),也就是字母d。

用pop()删除元素

pop()从列表中取出最后一个元素交给你。这说明,你可以为它指派一个名字,也就是给它赋个变量,比如:

使用pop()时还可以提供一个索引,如:

在这里我们弹出了第2个字母(索引1),也就是b。弹出的元素赋给secondLetter,而且会从letters删除。

括号里没有提供参数时,pop()会返回最后一个元素,并把它从列表中删除。如果在括号里放入一个数时,pop(n)会给出这个索引位置上的元素,而且会把它从列表中删除。

如何查找列表中的元素?

查找列表中的元素通常有两种处理:

查找元素是否在列表中;

查找元素在列表中的位置(也就是索引号)。

in关键字

要找出某个元素是否在列表中,可以使用in关键字,例如:

'a' in letters部分是一个布尔或逻辑表达式。如果a在这个列表中,它会返回值True,否则返回False。

我们可以在交互模式中试试下面的命令:

可以看到,名为letters的列表中确实包含一个元素b,但是不包含元素e。所以b在列表中,而e不在列表中。

查找索引

为了找出一个元素位于列表中的什么位置,可以使用index()方法,如下:

所以我们知道c的索引是2,这说明c在列表中排第3位元素。

如何进行列表的排序?

列表是一种有顺序的集合,这说明列表中的元素有某种顺序,每个元素都有一个位置,所以它可以用索引去查找。一旦以某种顺序将元素放在列表中,它们就会保持这种顺序,除非用insert()、append()、remove()或pop()改变列表。不过这个顺序可能不是你真正想要的顺序。你可能希望列表在使用前已经排序。

使用sort()方法

sort()会自动按字母顺序对字符串从小到大排序,如果是数字,就会按数字顺序从小到大排序。

有一点很重要,你要知道sort()会在原地修改列表,这说明它会改变你提供的原始列表,而不是创建一个新的有序列表。所以,你不能这样做:

这样做,会得到“None”。必须分两步来完成,就像这样:

另一种排序方法-sorted()

还有一种方法可以得到一个列表的有序副本而不会影响原列表的顺序。Python提供了一个名为sorted()的函数可以完成这个功能。它的工作如下:

sorted()函数提供了原列表的一个有序副本。

按逆序排序

让一个列表按逆序排序有两种方法。

一种方法是先按正常方式对列表排序,然后对这个有序列表完成逆置(reverse),如下:

在这里我们看到一个新的列表方法reverse(),它会把列表中元素的顺序倒过来。

另一种方法是向sort()增加一个参数,直接让它按降序排序(从大到小):

这个参数名为reverse,它会按照你的意愿,将列表按逆序排序。

要记住,我们刚才讨论的所有排序和逆置都会对原来的列表做出修改。这说明你原来的列表已经没有了。如果希望保留原来的顺序,而对列表的副本进行排序,可以使用分片记法建立副本,也就是与原列表相等的另一个列表(有关的内容你可以再次回顾前面讨论过的列表分片知识):

可改变和不可改变

如果还记得在第2篇推文中的内容,我们说过,真正改变一个数或字符串是做不到的,你能改变的只是把一个名字指派到哪个数或字符串(换句话说,你只能移动标签,即名字或变量)。不过,Python中确实有一些可以改变的类型,列表就是其中之一。刚才已经看到列表可以追加或删除元素,另外列表中的元素还可以排序或逆置。

这两种不同的变量分别称为可改变和不可改变的变量。可改变是指“能够改变”或者“可以改变”。不可改变表示“不能改变”或者“不可以改变”。在Python中,数字和字符串是不可改变的(不能改变),而列表是可改变的(能够改变)。

元组-不可改变的列表

有些情况下你可能不希望列表可以改变。Python中有没有一种不可改变的列表呢?答案是肯定的。确实有一个名为元组(tuple)的类型,这就属于不可改变的列表。可以这样来建立元组:

my_tuple = ("red","green","blue")

这里使用了圆括号,而不是列表使用的中括号。

由于元组是不可改变的,所以不能对元组完成排序,也不能追加和删除元素。一旦用一组元素创建一个元组,它就会一直保持不变。

(中场休息……)

学习太久,听首歌休息一下!^_^

(接着来……)

考虑数据如何存储在程序中时,可以用图直观地表示,这很有用。如下:

变量其实就有一个值:

列表就像是把一行值串在一起:

那么,有时还需要一个包含行和列的表,如下:

像上述包含行和列的表,应如何保存数据表呢?

我们已经知道,列表中包含多个元素,可以把每个学生的成绩放在一个列表中,像这样的:

或者对应每个课程使用一个列表,如下:

可是这样的数据都只是独立的,如果希望把所有数据都收集在一起呢?

双重列表

我们可以建立一个数据结构,就像下面那样:

这会得到一个元素列表,其中每个元素本身又是一个列表。我们创建了一个“列表的列表”(list of list),也就是双重列表。classMarks列表中的每个元素本身又都是一个列表。

当然,我们还可以直接创建classMarks,而不需要先创建joeMarks、tomMarks和bethMarks,如下:

现在我们试试显示一下classMarks双重列表中的数据结构:classMarks有3个元素,每个元素分别对应一个学生。所以可以使用in来循环处理,即如下:

这里我们对名为classMarks的列表完成循环处理。循环变量是studentMarks。每次循环时,会打印列表中的一个元素。这里的每一个元素分别是一个学生的成绩,它本身也是一个列表。

可以注意到,这看上去与前一页的表很类似,所以我们提出的这种数据结构可以把所有数据都保存在一个地方。

如何从双重列表中获取一个值?

我们已经知道,第一个学生的成绩(joeMarks)在一个列表中,而这个列表本身又是classMarks中的第一个元素。

下面来检查一下:

classMarks[0]是Joe的4门课程成绩的一个列表。

如果说,我们想从classMarks[0](Joe的4门课程成绩列表)中得到第三课程(即reading课程)的成绩77分,可以使用第二个索引获得。如下:

可以看到classMarks中的第一个索引0,也就是指Joe的成绩列表,而第二个索引2,则指Joe的成绩列表中的第三个元素。看到一个名字后面带着两组中括号时,比如说classMarks[0][2],这往往表示一个双重列表。

我们还可以形象的对classMarks表中加上标签,这样会更容易看出双重列表的获取原理:

其实classMarks列表并不知道Joe、Tom和Beth这些名字,也不知道Math、Seience、Reading和spelling这些课程。这里之所以这样标,是因为我们知道想要在这个列表中储存什么信息。

不过,对于Python来说,它们只是列表中一些已经编号的位置而已。这就像邮局里编号的邮箱,邮箱上没有名字,只有编号。邮递员只负责明确哪封信归哪个邮箱,而你知道哪个邮箱是你的。

如果要编写一个程序使用classMarks类似的双重列表来存储我们的数据,必须知道哪些数据存储在哪一行哪一列。就像邮递员一样,我们的任务是明确哪个位置属于哪个数据。

从上文可以看出,Python列表一种将元素组织在一起的方式。在编程中,你会经常想以另一种方式组织元素,即将某个值和另一个值关联起来。这种组织方式就像电话通讯录将姓名和电话号码关联起来,也像字典将单词和它们的含义关联起来。

字典

Python字典(dictionary)是一种将两个东西关联在一起的方式。被关联在一起的两个东西分别称为键(key)和值(value)。字典中的每个项(item)或条目(entry)都有一个键和一个值,它们合起来被称为键值对(key-value pair)。一个字典就是一些键值对的集合。

一个简单的例子就是电话通讯录。假设你想保存朋友们的电话号码。你会使用他们的姓名去查找他们的号码。这个姓名就是“键”,即你会用它来查找信息,而电话号码就是“值”,即你要查找的信息。

下面是创建一个Python字典的方法,我们用它来存储姓名和电话号码。首先, 创建一个空的字典:

这个代码看起来和创建的列表的方式非常像,只不过它使用的是花括号({ })而不是方括号([ ])。

然后,我们来添加一个条目:

如果我们打印一下字典,它看起来是这样的:

首先显示键,然后是一个冒号,再接着显示值。之所以用引号,是因为在这个例子中键和值麻将好都是字符串(不是必需的)。

也可以用另一种方式来完成:

我们来添加更多的条目。不像在列表中可以使用append(),在字典则没有用于添加新条目的方法。只需要指定新的键和值就行了:

我们来看一下整个字典:

我们之所以创建字典,是因为我们可以在字典中查找东西。在这个例子中,我们希望按姓名来查找电话号码。你可以这样做:

注意,这里使用方括号来指定你想要找的条目的键。整个字典本身还是被包裹在花括号中。

字典和列表有点类似,但也有一些主要区别。这两种类型都称为“集合”(collection),也就是说,它们都是将其他类型条目集中在一起的组织方式。

它们的一些相似点:

列表和字典都可以包含任意类型(甚至包括列表和字典)的条目,所以你可心有一个包含数字、字符串、对象甚至其他集合的集合。

列表和字典都提供了在集合中查找条目的方法。

它们的一些不同点:

列表是有顺序的。如果你按照某种顺序向列表中添加元素,这些元素就会保持这种顺序。你还可以对列表进行排序。

字典是无序的。如果你向字典中添加内容,然后打印出来,显示的顺序可能会跟添加的顺序不同。

列表中的元素是使用索引访问的,而字典中的条目是使用键来访问的:

前面提到过,在Python中很多东西都是对象,列表和字典也是。所以列表和字典都有一些使用点号(.)表示法来使用的方法。

keys()方法会列出字典中所有的键:

values()方法会列出字典中所有的值:

和列表一样,字典中的条目也可以是任意类型,包括简单类型(整数、浮点数、字符串)和集合(列表、字典)以及复合类型(对象)。

我们需要注意的是,只有字典中的值是可以使用字典的,而键的要求更为严格一些。早先我们谈论过可变类型与不可变类型。字典的键只可以使用不可变类型(布尔、整数、浮点数、字符串和元组)。你不能使用一个列表或者字典来当作键,因为它们是可变类型。

下面是字典可以做的其他一些事情。

使用del删除一个条目:

使用clear()删除所有条目(清空字典):

使用in确定某个键在字典中是否存在:

字典在Python代码中使用得很广泛。以上当然不是有关Python字典的全部内容,但你应该对其 有了大致的了解,这样你就可以在代码中使用字典,也可以认出在其他代码中出现的字典。

END

回顾

列表是什么。

如何向列表中增加元素。

如何从列表中删除元素。

如何确定列表是否包含某个值。

如何对列表排序。

如何建立列表的副本。

元组。

双重列表。

字典。

测试题

向列表增加元素有哪些方法?

从列表删除元素有哪些方法?

要得到一个列表的有序副本,但又不能改变原来的列表,有哪两种方法?

怎样得出某个值是否在列表中?

如何确定某个值在列表中的位置?

什么是元组?

如何建立双重列表?

如何从一个双重列表中得到一个值?

什么是字典?

如何向字典中增加项?

怎样使用键去查找一个条目?

动手试一试

写一个程序,让用户提供5个名字。程序要把这5个名字保存在一个列表中,最后打印出来。就像这样:

修改第1题的程序,要求不仅显示原来的名字列表,还要显示出排序后的列表。

修改第1题的程序,要求只显示用户键入的第3个名字,就像这样:

修改第1题的程序,让用户替换其中一个名字。用户应该能选择要替换哪个名字,然后键入新名字。最后显示这个新的列表:

编写一个字典程序,让用户可以添加单词和定义,然后可以查找这些单词。确保当要查找的单词不存在时,用户能够知晓。运行的时候,它应该是像这样的:

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180218G0AGK900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券