13: 序列 (数组)

序列是一串变量集合在一起,以同一个名字命名。序列不像是一个有很多变量x0, x1, x2的程序,而更像是一个变量x,并能够提取其中的成员x[0], x[1], x[2]等。你还可以将其他的表达式和变量放在中括号里,比如x[i]x[i+1]。这让我们可以通过仅使用一小段代码处理任意大的数据。

创建一个序列的方式是把一些值合在一起,放在中括号里,并用逗号给隔开:

myList = ["the first value in the list", 1999, 4.5]
这创建了一个序列,名为myList,长度为3。序列的每一项都有一个名为index的数字对应:第一个元素的索引是0,下一个元素索引是1,以此类推。单个的变量由序列构成,名字是

«listName»[«indexNumber»]

在这个例子中,myList[0]是一个变量,变量的值是字符串"the first value in the list"print(myList[2]) would print 4.5。你也可以改变序列中每一项的值,并将整个序列打印出来:

示例
更新并打印序列。

正如你所看到的那样,numbers[0]被当作成一个变量:拥有一个值,这个值也可以改变。

接下来,尝试预测下列例子的最后状态,然后与实际情况比对。

选择题练习: 元信息
下列代码的输出是什么?

stuff = [2, 25, 80, 12]
stuff[stuff[0]] = stuff[3]
print(stuff)
正确!请看指定陈述(第二行)。右侧的stuff[3]的值12。在左侧,stuff[0]2,所以stuff[stuff[0]]代表了变量stuff[2]。这个变量的值被更新(从80)到12

Python里面的序列在其他编程语言里面被叫做数组。Python 里有一些不同且更加高级的东西&amp,也被称作数组。

常见的错误

在Python里,调用一个不存在的索引会得到错误提示:

示例
范围外错误。

在上面的例子中,因为myList长度为4,第一个索引是0,最大可能的索引值是3。如果想要索引4或5,或更大的索引值,就会收到错误提示。

常见有用的运算

序列的长度: len(«list»)

为了得出序列中项目的个数,在该序列上运用方程len()。查看range是如何在下列例子中使用的。

示例
得到序列的长度,使用其结果来对序列迭代。

通常使用len 来编写代码,这些代码可以用于任何长度的序列,正如上面的例子和下面的练习一样。

编程练习: Monkey in the Middle
编写一个方程middle(L),将序列L 作为它的实参,返还L中间项(假设L是奇数长度)。比如,middle([8, 0, 100, 12, 1])会返还100,因为100是正当中的项。

序列和字符串一样么?

你可能已经注意到了有关序列的方程与字符串的方程相似:两个都能使用len()方程来获得长度,两个都能使用X[«index»]来提取出个体。序列和字符串实际上是相关的:它们都是Python中的"序列类型"。其中一个主要的区别在于字符串中单个的字符不能被改变。

示例
尝试将一个值归于字符串中的一个字符导致了错误。

因为这个原因,序列被称作可改变的类型,字符串是不可改变的;你会在第17课看到有关于此的信息。

串联与创造

在有关str类型的这一课,你可能记得可以使用+来融合(串联)两个字符串。你可以对序列做同样的事情:

示例
使用+合并数列。

同样,你可以使用乘法符号*来通过重复扩充一个序列。这有助于创建一个新的固定长度的序列。

示例
使用*

下一个练习题需要使用我们刚介绍的一个运算符,以及for循环。

编程练习: It's Natural
编写一个方程naturalNumbers,需要一个正整数n作为输入,返还一个由前n个自然数组成的序列[1, 2, ...]

行末:负指数

为了得到序列的最后一项,使用

«listName»[-1]

一般来说,L[-k]返还序列倒数第k个项;Python通过将其转化成L[len(L)-k]从内部解决这个问题。这个快捷符号对字符串也适用!

编程练习: 回文
回文意味着一个词正着看,倒着看都一样。比如,

racecar

回文:第一个和最后一个字母都是r,第二个和最后一个字母都是a,以此类推。编写一个方程isPalindrome(S),需要一个字符串S作为输入,如果字符串是一个回文词,返还True,否则为False。

maxsum

我们之前见到的方程max 也可以用于序列数字:它返还序列中最大的数字。同样,方程sum(L)返还序列L中所有项的和。

示例

编程练习: Product
定义一个方程prod(L),返还序列L中所有项的乘积。

循环序列

将一个序列中每一个值都循环(与前面的例子类似)是非常普遍的。Python中有一个快捷方式来进行这项操作,通常被称为"for all"循环,或者"for each"循环。具体来说,当L是一个序列,这个代码

for x in L:
  «loop body block»
进行以下操作:第一个x被设置成L序列中第一项,然后运行主体;然后x再被设置成L序列中第二项,然后运行主体;以此类推,直到L序列里面的所有项。

下面是一个可视化的例子,来打印出序列中的项:

编程练习: for in
定义方程prod(L),但是这一次使用新的循环。

"For all"循环也适用于字符串:尝试for char in "hello".

做得好!现在你可以进行下一课的学习了,或者你可以试试下面的练习题。


简答练习: Mystery Function
x为何值时,会使mystery(x)一直运行下去?

def mystery(x):
  a = [0, 4, 0, 3, 2]
  while x > 0:
    x = a[x]
  return "Done"
正确!

综合练习: à la Mode
一个序列的众数是出现次数最多的数字(频率最大)。整理下面的程序,使得mode(L)能够正确地找到众数,假设L是一个由从0到9数字组成的序列(不必考虑出现两个数字拥有同样的频率的情况)。
  • frequency = [0]*10
  • for i in L:
  • def mode(L):
  • return i
  • if frequency[i]==max(frequency):
  • frequency[i] = frequency[i] + 1
  • for i in range(0, 10):