python 中的序列

python 中的序列

序列概述

Python 内置了多种序列,比如列表、元组和字符串。

列表和元组的主要不同在于:列表是可以修改的,而元组不可以。

在需要处理一系列值时,序列很有用。在数据库中,你可能使用序列来表示人,其中第一个元素为姓名,第二个元素为年龄。如果使用列表来表示,将类似于下面这样:

>>> edward = ['Edward Gumby', 42] 

要点是:所有元素都放在方括号内,并用逗号隔开。

有的人喜欢把列表看成是 C 语言中的数组。它们确实有相似性,但请你注意:C 语言中的数组都是相同类型的元素,而 Python 的列表可以是不同类型的元素。

序列内还可以包含其他序列,比如:

>>> edward = ['Edward Gumby', 42] 
>>> john = ['John Smith', 50] 
>>> database = [edward, john] 
>>> database 
[['Edward Gumby', 42], ['John Smith', 50]] 

注意

Python支持一种数据结构的基本概念,叫做“容器”(container)。容器基本上就是可包含其他对象的对象。两种主要的容器是序列(如列表和元组)和映射(如字典)。在序列中,每个元素都有编号,而在映射中,每个元素都有键。有一种既不是序列也不是映射的容器,它就是集合(set)。

通用的序列操作

有几种操作适用于所有序列,这些操作是索引、切片、相加、相乘、成员资格检查和迭代等。另外,Python 还提供了一些内置函数,可用于确定序列的长度以及找出序列中最大和最小的元素。

索引(indexing)

序列中的所有元素都有编号——从0开始递增。你可像下面这样使用编号来访问各个元素:

>>> greeting = 'Hello' 
>>> greeting[0] 
'H' 

其实这和 C 语言中的字符串很像。

字符串就是由字符组成的序列。索引0指向第一个元素,这里为字母H。不同于其他一些语言,Python 没有专门用于表示字符的类型,因此一个字符就是只包含一个元素的字符串。

当你使用负数索引时,Python 将从右(即从最后一个元素)开始往左数,因此 -1 是最后一个元素的位置。

>>> greeting[-1] 
'o' 

对于字符串字面量(以及其他的序列字面量),可直接对其执行索引操作,无需先将其赋给变量。

>>> 'Hello'[1] 
'e' 

其实在 C 语言中也可以这样,比如:

#include <stdio.h>

int main(void)
{
    printf("%c\r\n", "HelloWorld"[1]);
    return 0;
}

以上这段代码的运行结果是:

e

如果函数调用返回一个序列,可直接对其执行索引操作。例如,如果你只想获取用户输入的年份的第4位,可这样做:

In [3]: fourth = input("Year : ")[3]
Year : 1998

In [4]: fourth
Out[4]: '8'

以上操作是在 ipython 中演示的,ipython 是什么呢?

IPython provides a rich architecture for interactive computing with:

  • A powerful interactive shell.
  • A kernel for Jupyter.
  • Support for interactive data visualization and use of GUI toolkits.
  • Flexible, embeddable interpreters to load into your own projects.
  • Easy to use, high performance tools for parallel computing.

​ —— 摘自 https://ipython.org/

切片(slicing)

除了使用索引来访问单个元素外,还可使用切片(slicing)来访问特定范围内的元素。为此,可使用两个索引,并用冒号分隔,比如

In [5]: nums=[1,2,3,4,5,6,7,8,9,10]

In [6]: nums[3:6]
Out[6]: [4, 5, 6]

In [7]: nums[0:1]
Out[7]: [1]

注意:第一个索引是包含的第一个元素的编号,但第二个索引是切片后余下的第一个元素的编号。

简而言之,你提供两个索引来指定切片的边界,其中第一个索引指定的元素包含在切片内,但第二个索引指定的元素不包含在切片内。

利用简写

假设你要访问前述列表 nums 中的最后三个元素,可以这样写:

>>> nums[7:10] 
[8, 9, 10] 

在这里,索引10指的是第11个元素,虽然它并不存在,但确实是到达最后一个元素后再前进一步的位置。

切片中也可使用负数索引。

>>> nums[-3:-1] 
[8, 9] 

然而,这样好像无法包含最后一个元素。如果使用索引0,即到达列表末尾后再前进一步所处的位置,结果将如何呢?

在 ipython 中的结果如下:

In [5]: nums[-3:0]
Out[5]: []

结果并不是你想要的。事实上,执行切片操作时,如果第一个索引指定的元素位于第二个索引指定的元素后面(在这里,倒数第3个元素位于第1个元素后面),结果就为空序列。

还好,我们可以使用一种简写:如果切片结束于序列末尾,可省略第二个索引。

In [6]: nums[-3:]
Out[6]: [8, 9, 10]

同理,如果切片始于序列开头,可省略第一个索引。

In [7]: nums[:3]
Out[7]: [1, 2, 3]

要复制整个序列,可将两个索引都省略,在方括号内只留一个冒号。

In [8]: nums[:]
Out[8]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
步长

执行切片操作时,你显式或隐式地指定起点和终点,但通常省略了另一个参数,即步长。默认步长为1。这意味着从一个元素移到下一个元素,因此切片包含起点和终点之间的所有元素。

In [9]: nums[0:10:1]
Out[9]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

如果指定的步长大于1,将跳过一些元素。例如,步长为2时,将从起点和终点之间每隔一个元素提取一个元素。

In [10]: nums[0:10:2]
Out[10]: [1, 3, 5, 7, 9]
    
In [11]: nums[0:10:3]
Out[11]: [1, 4, 7, 10]

显式地指定步长时,也可使用前述简写。例如,要从序列中每隔3个元素提取1个,只需提供步长4即可。

In [12]: nums[::4]
Out[12]: [1, 5, 9]

当然,步长不能为0,否则无法向前移动。

In [14]: nums[1:7:0]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-7219eb36c975> in <module>()
----> 1 nums[1:7:0]

ValueError: slice step cannot be zero

步长可以为负数,即从右向左提取元素。

In [15]: nums[::-1]
Out[15]: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
In [16]: nums[10:0:-2]
Out[16]: [10, 8, 6, 4, 2]

上面的结果,有人会疑惑。他这样想:从10开始,也就是第11个元素,即最后一个元素的后面,然后向左走2步,应该是9,7,5,3,1 才对。

开始我也挺疑惑的,后来才明白,因为没有10,最多是9,所以这里的10就相当于9。

In [19]: nums[9:0:-2]
Out[19]: [10, 8, 6, 4, 2]
In [20]: nums[0:10:-2]
Out[20]: []

上面这个结果又是为什么呢?

步长为负数时,第一个索引必须比第二个索引大。步长为正表示从左向右走,为负表示从右向左走。想象有一个数轴,从0向左走,是走不到10的,所以结果为空。

In [22]: nums[::-2]
Out[22]: [10, 8, 6, 4, 2]

当省略起始和结束索引时,Python 竟然执行了正确的操作:步长为正数时,它从起点移到终点,而步长为负数时,它从终点移到起点。

In [23]: nums
Out[23]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In [24]: nums[:5:-2]
Out[24]: [10, 8]

In [25]: nums[5::-2]
Out[25]: [6, 4, 2]

请看第4行,省略的索引,到底是左边的起点还是右边的终点呢?因为步长是负数,所以一定是从右往左走,所以省略的是右边的10;

第7行,因为步长为负数,所以应该从右向左,所以省略的索引是0;

In [26]: nums[10:5:-2]
Out[26]: [10, 8]

In [27]: nums[5:0:-2]
Out[27]: [6, 4, 2]

可以看到,和之前的结果是一样的。

序列相加

可使用加法运算符来拼接序列。

In [28]: [1,2,3]+[4,5,6,7]
Out[28]: [1, 2, 3, 4, 5, 6, 7]

In [29]: "hello"+" "+"world"
Out[29]: 'hello world'

一般而言,不能拼接不同类型的序列。

In [30]: [1,2,3]+"hello"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-9346ef22b4d4> in <module>()
----> 1 [1,2,3]+"hello"

TypeError: can only concatenate list (not "str") to list

乘法

将序列与数 N 相乘时,将重复这个序列 N 次来创建一个新序列:

In [31]: "H"*6
Out[31]: 'HHHHHH'

In [32]: 10*"Hello"
Out[32]: 'HelloHelloHelloHelloHelloHelloHelloHelloHelloHello'

In [34]: [32,1]*3
Out[34]: [32, 1, 32, 1, 32, 1]

None、空列表和初始化

空列表是使用不包含任何内容的两个方括号表示的。

In [43]: list=[]

In [44]: list
Out[44]: []

如果要创建一个可包含10个元素的列表,但没有任何有用的内容,你可以使用[0]*10,这将创建一个包含10个零的列表。然而,在有些情况下,你可能想使用表示“什么都没有”的值,在这种情况下,可使用 None。在Python中,None表示什么都没有。因此,要将列表的长度初始化为10,可像下面这样做:

In [35]: seq=[None]*10

In [36]: seq
Out[36]: [None, None, None, None, None, None, None, None, None, None]

成员资格

要检查特定的值是否包含在序列中,可使用运算符in。它检查是否满足指定的条件,并返回相应的值:满足时返回True,不满足时返回False。这样的运算符称为布尔运算符,而前述真值称为布尔值。

下面是一些例子。

In [48]: permission='rw'

In [49]: 'w' in permission
Out[49]: True

In [50]: 'x' in permission
Out[50]: False

记住 w 两侧要加引号。否则会报错。

In [51]: w in permission
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-51-7a03fc4c0ccc> in <module>()
----> 1 w in permission

NameError: name 'w' is not defined

In [56]: option=['a','b','c']

In [57]: input("a/b/c: ") in option
a/b/c: b
Out[57]: True

In [58]: input("a/b/c: ") in option
a/b/c: d
Out[58]: False

In [59]: subject = '$$$ Get rich now!!! $$$' 

In [60]: "$$" in subject
Out[60]: True

如上所示,可使用运算符 in 来检查指定的字符串是否为另一个字符串的子串。

长度、最小值和最大值

内置函数len、min和max很有用,其中函数len返回序列包含的元素个数,而min和max分别返回序列中最小和最大的元素。

In [67]: numbers =[100, 77, 12]

In [68]: len(numbers)
Out[68]: 3

In [69]: max(numbers)
Out[69]: 100

In [70]: min(numbers)
Out[70]: 12

In [71]: subject="Hello!"

In [72]: len(subject)
Out[72]: 6

In [64]: my_string = "abcdefg"

In [65]: max(my_string)
Out[65]: 'g'

In [66]: min(my_string)
Out[66]: 'a'

【End】

参考资料

《Python基础教程(第三版)》,人民邮电出版社

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值