基于股票大数据分析的Python入门实战(视频教学版)
上QQ阅读APP看书,第一时间看更新

2.1 列表和元组能存储线性表型数据

在用Java语言学数据结构时,会了解到这样的知识:第一,数组和链表是不同数据结构的对象;第二,在数组中,查找特定索引位置元素的效率比链表快,但插入和删除元素的效率却没链表高。不过,这和Python语言中定义线性表的方式不同,所以上述知识点无法应用在Python中。

在Python语言中,数组是个统称,它有三种类型:第一类是链表型,在其中可以动态添加和删除数据,本书中称此类型为列表(List);第二类是元组型(Tuple),一旦定义后,其中的元素不能被修改;第三类是字典型(Dictionary),在这类数组中能存储若干个键-值对(Key-Value Pair)类型的数据。

2.1.1 列表的常见用法

列表是Python中常见的集合类数据结构,在下面的ListDemo.py范例程序中演示了Python数组的常见用法,需要注意的是:尽量不要在其中存储不同类型的数据。

1    # !/usr/bin/env python
2    # coding=utf-8
3    # 定义多个类型的列表
4    priceList=[10.58,25.47,100.58]     # 浮点型列表
5    cityList=["ShangHai", "HangZhou", "NanJing"] # 字符串类型列表
6    mixList=[1, 3.14, "Company"]         # 混合类型的列表,谨慎使用
7    
8    # 在控制台输出
9    print(priceList)      #[10.58, 25.47, 100.58]
10    print(cityList)       #['ShangHai', 'HangZhou', 'NanJing']
11    print(mixList)        #[1, 3.14, 'Company']
12    
13    del mixList[2]
14    print(mixList)          # 没有了最后一个元素
15    # mixArr.remove(2)     # 去掉没有的元素,也会抛出异常
16    mixList.remove(1)
17    print(mixList)         # 也看不到1了
18    
19    print(priceList[0])           # 获得数组指定位置的元素,这里输出是10.58
20    priceList.append(200.74)     # 添加元素
21    print(priceList)               # 能看到添加后的元素
22    print(cityList.index("ShangHai"));
23    #print(cityList.index("DaLian")); # 如果找不到,会抛出异常并终止程序

在上述范例程序代码中,演示了针对列表的常见用法,通过注释可以知道关键代码的含义,而且在各个输出语句的位置也通过注释说明了输出的结果。这里,请读者注意如下的要点。

(1)在定义列表时,如果没有特殊的需求,请不要像第6行那样,在列表中定义了不同类型的数据,因为在处理时不得不先判断数据的类型再进行针对性的读取,这样会增加代码的复杂度,非常不利于程序的维护。

(2)可以通过del和remove来删除元素,但在使用remove删除元素时,需要保证该元素存在,否则就会抛出异常,从而导致程序异常中止。如果去掉第15行的注释符号,就能看到因删除不存在元素而导致抛出异常的结果。如果希望在删除不存在元素时不抛出异常,那么可以调用discard方法。

(3)可以像第19行那样,通过诸如priceList[0]的形式,以索引的方式操作其中的具体元素,这里请注意,元素的索引值是从0开始,priceArr[0]表示的是列表中的第一个元素。

(4)可以像第22行那样,用index的方式在数组里查找元素,如果找到,返回的是该元素的索引位置,同样请注意,如果去掉第23行的注释符号,去找一个不存在的元素,就会抛出异常而导致程序意外中止。

在实际的程序项目中,如果出现异常,我们期望的结果是,看到错误提示,同时程序继续执行。不过,在这个范例程序中,我们看到的是“抛出异常,程序意外中止”的结果,这种中止程序执行的做法是比较危险的,所以在本书的后续部分,会通过“异常处理机制”来专门解决这类问题。

2.1.2 链表、列表还是数组?这仅仅是叫法的不同

在2.1.1小节提到,链表类数组是数组类型的一种,所以在上一节范例程序中定义的priceArr对象,称它为链表(有人也称它列表)和数组,都不算错。事实上,Python由于是弱数据类型的语言,即定义元素时无需定义数据类型,因此从使用方式上来看,列表(List)和数组(Array)的差别确实不大。

如果大家熟悉数据结构的知识,就会发现列表和数据在底层的实现是不同的,这在Java或C#等强数据类型(即定义元素必须要给出数据类型)的语言中确实会是个问题,但在Python语言中则不是。

通过Python语言给出的接口,我们可以用同一种方式来操作列表和数组,无需也无从选择,不能像Java等语言一样,在定义时必须强制指定是数组还是列表。

既然无从选择,那么可以这样说,在Python中,数组和列表其实是相通的,也就是用起来一样,但为了不让大家混淆,本书会把列表型的数组也称为“列表”,而尽量不出现“数组”的字样。

2.1.3 对列表中元素进行操作的方法

在常见的数据分析和统计场景中使用列表,可以调用Python提供的诸如排序和求最大值等操作列表中元素的方法。在下面的ListSeniorUsage.py范例程序中,可以看到操作列表中数据的常用方法。

1    # !/usr/bin/env python
2    # coding=utf-8
3    
4    priceList=[10.58,25.47,100.58,500.47]
5    cityList=["ShangHai", "HangZhou", "NanJing"]
6    # 进行排序
7    priceList.sort()
8    print(priceList);
9    # print(priceList.sort());     # 错误的用法
10    
11    print(sum(priceList))         # 求和
12    print(max(priceList))         # 求最大值,输出500.47
13    print(min(cityList))          # 求最小值,输出HangZhou
14    
15    subList=priceList[1:3]     # 截取列表中元素
16    print(subList)                 # 输出[25.47, 100.58]

在第7行中,对priceList进行了排序,如果要输出排序后的列表,应该如第8行那样,而不能像第9行那样直接打印priceList.sort()。

从第11行到第13行的程序语句,分别执行了求和,求最大值和最小值的操作。其中第13行是对字符串型列表中的字符串求最小值,结果是按字母顺序排序字符串并返回最小的字符串。

第15行的程序语句是截取了列表中的部分元素,请注意,冒号前的参数表示从哪个索引位置开始截取,索引值也是从0开始,语句中的1,表示从第2个元素开始。这里需特别注意,冒号后的参数表示截取到哪个索引位置,这条语句中是3,表示截取到列表的第4个元素之前,但不含第4个元素(不含500.47这个元素)。

2.1.4 不能修改元组内的元素

在前文中,是通过方括号来定义列表,而元组(Tuple)是通过“()”来定义的。

元组内的元素不能被修改,具体含义就是:第一,不能修改和删除其中的元素;第二,创建好的元组无法再向其中添加元素。不过,可以针对整个元组进行其他操作。在实际应用中,一般用元组来存储不会变更的常量元素。在下面的TupleDemo.py代码中演示了元组的常见用法。

1    # !/usr/bin/env python
2    # coding=utf-8
3    # 定义两个元组
4    cityTup=("TianJin","WuHan","ChengDu")
5    # cityTup[0]="HeFei" # 会抛出异常
6    # del cityTup[0]    # 无法删除其中的元素,则会抛出异常
7    print(cityTup)      # 输出结果是('TianJin', 'WuHan', 'ChengDu')
8    # 把列表转为元组
9    bookList=["Python book","Java Book"]
10    bookTup=tuple(bookList)
11    
12    # 查询操作
13    print(cityTup[1])      # 输出WuHan
14    print(cityTup[0:2])     # 输出('TianJin', 'WuHan')
15    
16    # 统计元组里指定元素的个数
17    print(cityTup.count("TianJin"))  # 返回1
18    # 统计元组的长度
19    print(len(cityTup))  # 返回3
20    
21    # 只能删除整个元组对象
22    del cityTup

范例程序的第4行通过小括号的方式定义了一个名为cityTup的元组,第5行的程序语句企图修改这个元组的第1个元素,由于元组无法被修改,因此会抛出异常。第9行的代码定义了一个列表,之后通过第10行的tuple方法,把列表转换成了元组,这样bookTup也就无法被修改了。

在第13和第14行中,以两种方式查询了元组内的元素,请注意,第14行语句中冒号前后的两个参数也是表示存取的“开始位置”和“终止位置”,截止到终止位置之前的元素都会输出,但终止位置的元素不会被输出。

在第17行中,调用count方法统计元组内指定元素出现的次数,在第19行中,通过调用len方法打印输出元组的长度。虽然我们无法删除元组中的单个元素,但却可以通过调用del方法删除整个元组,如第22行那样。