列表是可修改的序列,可以存放任何类型的数据,用[]表示。列表中的元素用逗号间隔,每个元素按照先后顺序有索引号,索引号的基数为0。列表创建以后,可以进行索引、切片、增删改查和排序等各种操作。
创建列表
可用多种方法创建列表。
一、使用[]创建
可用中括号[]直接创建列表。下面创建一个没有元素的列表。
>>> a=[]
创建一个元素为一组数据的列表。
>>> a=[1,2,3,4,5]
>>> a
[1, 2, 3, 4, 5]
创建一个元素为一组字符串的列表。
>>> a=["excel","python","dqexcel"]
>>> a
['excel', 'python', 'dqexcel']
列表元素的数据类型可以不同,例如:
>>> a=[1,5, "b",False]
>>> a
[1, 5, 'b', False]
列表的元素也可以是列表。
>>> a=[[1],[2],3,"dqexcel"]
>>> a
[[1], [2], 3, 'dqexcel']
二、使用list函数创建
使用list函数能将任何可以迭代的数据转换成列表。可迭代数据包括字符串、区间、元组、字典、集合等数据。
该函数不带参数时创建一个空的列表,
>>> a=list()
>>> a
[]
把字符串转换为列表
该函数的参数为字符串时,将该字符串转换为元素为字符串各字符组成的列表。
>>> a=list("hello")
>>> a
['h', 'e', 'l', 'l', 'o']
把区间对象转为列表
用range函数创建一个区间对象,该对象在指定的范围内连续取值。range函数可有1个、2个或3个参数。有3个参数时指定区间的起点、终点和间隔的步长,比如从2开始,每隔2个数取一次数,取到10为止。有2个参数时指定起点和终点,步长取1。有1个参数时指定终点,起点取0,步长取1。
下面是range函数只有1个参数的情况。
>>> rg1=range(8)
>>> rg1
range(0, 8)
生成的区间对象从0开始,以1为间隔连续取8个值,即0-7。所以,虽然表面上看range(0, 8)定义的区间终点为8,实际上不包括8,这习惯上称为“包头不包尾”。可以用中括号和索引号获取区间对象的值,例如下面取区间第1个值和最后1个值:
>>> rg1[0];rg1[7]
0
7
下面是range函数有3个参数的情况,在0到9范围内每隔2个数取一次数:
>>> rg2=range(0,10,2)
>>> rg2
range(0, 10, 2)
通过索引获取区间前两个数:
>>> rg2[0];rg2[1]
0
2
可见相邻两个数之间的间隔为2。
将区间对象作为list函数的参数可以创建列表。
>>> a=list(rg1)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7]
>>> b=list(rg2)
>>> b
[0, 2, 4, 6, 8]
把元组、字典和集合转换为列表
使用list函数也可以把元组、字典和集合等可迭代对象转换为列表。关于元组、字典和集合,将在后面章节陆续介绍,这里先看操作效果。
将元组转换为列表:
>>> a=(1,"abc",True)
>>> list(a)
[1, 'abc', True]
将字典转换为列表:
>>> a={"大谦":89,"李四":92}
>>> list(a)
['大谦', '李四']
将集合转换为列表:
>>> a={1,"abc",123,"hi"}
>>> list(a)
[1, 123, 'hi', 'abc']
三、列表基本操作
使用len函数获取列表的长度。
>>> a=[1,2,3,4,5,6]
>>> len(a)
6
使用列表对象的count方法指定元素在列表中出现的次数。下面创建一个列表,计算元素2在列表中出现的次数。
>>> a=[1,2,3,2,4,5,2,6]
>>> a.count(2)
3
使用成员运算符in或not in判断列表中包含或不包含指定元素,条件满足时返回True,否则返回False。下面判断给定列表中是否包含元素1,是否不包含元素4:
>>> 1 in [1, 2, 3]
True
>>> 4 not in [1, 2, 3]
True
使用print函数对列表数据进行格式化输出时使用索引获取列表的元素。下面创建一个列表,然后用print函数进行格式化输出。
>>> student = ["张三","95"]
>>> print("姓名:{0[0]}, 数学成绩:{0[1]}".format(student))
姓名:张三, 数学成绩:95
使用for循环遍历列表。下面对区间应用for循环,逐个输出区间里面的每个数字。
>>> for i in range(6):
print("当前数字:", i)
下面对列表应用for循环,逐个输出列表中的每个城市名称。
>>> ads=["北京","上海","广州"]
>>> for ad in ads:
print("当前地点:",ad)
对于列表,也可以使用区间,结合列表索引来输出列表中的元素。下面用索引输出列表中各城市的名称。
>>> ads=['北京','上海','广州']
>>> for index in range(len(ads)):
print("当前地点:",ads[index])
四、深入列表
列表中的每个元素都引用一个对象,每个对象有自己的内存存储地址、数据类型和值。各元素保存对应对象的地址。
下面创建一个列表,用id函数获取列表中各元素引用的对象的地址。
>>> a=[1,2,3]
>>> id(a[0])
8791520672832
>>> id(a[1])
8791520672864
>>> id(a[2])
8791520672896
可见,各元素引用的对象的地址各不相同,它们是不同的对象。
索引和切片
创建列表和向列表添加元素后,如果希望获取列表中的某个或某部分元素并对它们进行后续操作,就要用到索引和切片。索引一般是访问列表中的某个元素,切片则连续访问列表中的部分元素。
使用[]进行列表索引操作,中括号中为要索引的元素在列表中的索引号。从左到右索引时,索引号的基数为0;从右到左索引时,索引号的基数为-1。
下面创建一个列表ls:
>>> ls=["a","b","c"]
通过索引获取列表中的第3个元素:
>>> ls[2]
'c'
获取列表中倒数第2个元素:
>>> ls[-2]
'b'
使用index方法获取指定元素在列表中首次出现的位置。语法格式为:
index(value.[start, [end]])
其中,value为指定的元素,start和end指定搜索的范围。
下面首先创建一个列表a:
>>> a=[1,2,3,4,2,5,6]
获取元素2在列表中第一次出现的位置,注意位置索引基数为0:
>>> a.index(2)
1
从第3个元素开始到最后一个元素,在这个范围内获取元素2第一次出现的位置:
>>> a.index(2,2)
4
切片操作从给定的列表中连续获取多个元素。常见的列表切片操作如表1- 所示。切片操作完整的定义是[start:end:step],取值范围的起点、终点和步长之间用冒号间隔。这3个参数都可以省略。注意“包头不包尾”原则。
从左往右切片时,位置索引的基数为0。省略start参数时,起点为列表的第1个元素;省略end参数时,终点为列表的最后一个元素;省略step参数时,步长为1。
从右往左切片时,位置索引的基数为-1。各参数的值都为负,数字的大小为从右边往左边数数的大小。比如最后一个元素的索引号为-1,倒数第2个为-2,如此类推。
各种切片操作的示例如表7-2中所示。
表7-2 列表的切片操作
| 切片操作 | 说明 | 示例 | 结果 |
|---|---|---|---|
| [:] | 提取整个列表 | [1,2,3,4,5] [:] | [1,2,3,4,5] |
| [start:] | 提取从start位置开始到结尾的元素组成列表 | [1,2,3,4,5] [2:] | [3,4,5] |
| [:end] | 提取从头到end-1位置的元素组成列表 | [1,2,3,4,5] [:2] | [1,2] |
| [start:end] | 提取从start到end-1位置的元素组成列表 | [1,2,3,4,5] [2:4] | [3,4] |
| [start:end:step] | 提取从start到end-1位置的元素组成列表,步长为step | [1,2,3,4,5] [1:4:2] | [2,4] |
| [-n:] | 倒数n个元素组成列表 | [1,2,3,4,5] [-3:] | [3,4,5] |
| [-m:-n] | 倒数第m个到倒数第n个元素组成列表 | [1,2,3,4,5] [-4:-2] | [2,3] |
| [::-s] | 步长为s,从右向左反向提取组成列表 | [1,2,3,4,5] [::-1] | [5,4,3,2,1] |
追加列表元素
列表创建以后,可以使用多种方法向列表中添加元素。
一、使用append方法
使用列表对象的append方法在其尾部添加新的元素。该方法的速度比较快。下面创建一个列表,然后用append方法添加一个元素。
>>> a=[1,2,3,4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
二、使用extend方法
跟append方法一样,使用extend方法也是在列表尾部添加新元素。跟append方法不同的是,它在列表末尾一次性追加另一个序列的多个值,所以,它更适合列表的拼接。
>>> a=[1,2,3,4]
>>> a.extend([5,6])
>>> a
[1, 2, 3, 4, 5, 6]
extend方法的参数还可以是字符串、区间、元组、字典和集合等可迭代对象。例如:
>>> a=[1,2]
>>> a.extend("abc") #追加字符串
>>> a
[1, 2, 'a', 'b', 'c']
>>> a.extend((3,4)) #追加元组
>>> a
[1, 2, 'a', 'b', 'c', 3, 4]
>>> a.extend(range(5,7)) #追加区间
>>> a
[1, 2, 'a', 'b', 'c', 3, 4, 5, 6]
三、使用运算符
使用加号(+)可以将两个列表连接起来,组成一个新的列表,如:
>>> [1, 2, 3]+[4, 5, 6]
[1, 2, 3, 4, 5, 6]
使用乘法扩展,可以将原有列表多次重复,生成新的列表。下面创建一个有2个元素的列表,将它扩展3倍,生成新的列表b。
>>> a=[1,"a"]
>>> b=a*3
>>> b
[1, 'a', 1, 'a', 1, 'a']
插入列表元素
使用列表对象的insert方法,可以在指定位置插入指定元素。该方法有两个参数,第1个参数指定插入的位置,指定一个索引号,即在它对应的对象前面插入新对象,索引号的基数为0;第2个参数指定插入的对象。
下面创建一个有4个元素的列表,使用列表对象的insert方法在第4个元素前面插入新对象5。
>>> a=[1,2,3,4]
>>> a.insert(3,5)
>>> a
[1, 2, 3, 5, 4]
删除列表元素
Python中,可以使用多种方法删除列表元素。
使用列表对象的pop方法可以删除指定位置的元素,如果没有指定位置,则删除列表末尾的元素。
下面创建一个列表,用其pop方法删除最后一个元素。
>>> a=[1,2,3,4,5,6]
>>> a.pop()
>>> a
[1, 2, 3, 4, 5]
继续删除列表中的第3个元素。注意位置索引号的基数为0。
>>> a.pop(2)
>>> a
[1, 2, 4, 5]
使用del命令删除指定位置的元素。下面删除列表中的第4个元素。
>>> a=[1,2,3,4,5,6]
>>> del a[3]
>>> a
[1, 2, 3, 5, 6]
pop方法和del命令都是使用索引删除列表元素,使用remove方法可以直接删除列表中首次出现的指定元素。下面从列表中直接删除第1个元素3。
>>> a=[1,2,3,4,5,6]
>>> a.remove(3)
>>> a
[1, 2, 4, 5, 6]
如果指定的元素在列表中不存在,返回一个出错信息。
>>> a.remove(10)
Traceback(most recent call last):
File "<pyshell#106>", line 1, in <module>
a.remove(10)
ValueError: list.remove(x): x not in list
列表元素去重
对列表进行去重,需要另外创建一个列表。对原始列表进行遍历,如果原始列表中的元素在新列表中不存在,则添加到新列表中,否则不添加。例如:
>>> a=[1,2,3,4,3,1] #有重复值的列表
>>> b=[1] #新列表
>>> for i in range(len(a)): #遍历原始列表
r=a[i] #原始列表中的当前值r
if r not in b: #如果r在新列表中不存在
b.append(r) #r添加到新列表
>>> b
[1, 2, 3, 4]
所以,最后新列表中重复的值被去除了。
列表元素排序
用列表对象的sort方法对列表中的元素进行排序。默认时为从小到大排序,不必设置方法参数。下面创建一个列表,用sort方法将列表元素从小到大进行排序。
>>> ls=[4,2,1,3]
>>> ls.sort()
>>> ls
[1,2,3,4]
设置sort方法reverse参数的值为True,对列表中的元素按照从大到小的顺序进行排列。
>>> ls.sort(reverse=True) #降序排列
>>> ls
[4,3,2,1]
还可以使用Python的内置函数sorted进行排序。该函数不对原列表进行修改,而是返回一个新的列表。设置方法的reverse参数的值为True,将列表元素进行降序排列。
>>> ls=[4,2,1,3]
>>> a=sorted(ls)
>>> a
[1,2,3,4]
>>> a=sorted(ls, reverse=True)
>>> a
[4,3,2,1]
列表元素的计算
使用max, min和sum等函数可以直接求取列表元素的最大值、最小值和累加和。下面创建一个列表,元素为数字0-10,对它们进行简单统计计算。
>>> a=range(11)
>>> max(a) #最大值
10
>>> min(a) #最小值
0
>>> sum(a) #和
55
另一种常见方法是使用NumPy包提供的统计分析函数进行计算。NumPy包是专门为数组计算设计的,具有功能函数多、计算速度快等特点。7.4节详细介绍NumPy包和NumPy数组,请参阅。
>>> import numpy as np #导入NumPy包
>>> a=range(11)
>>> np.amax(a) #最大值
10
>>> np.amin(a) #最小值
0
>>> np.sum(a) #和
55
>>> np.mean(a) #均值
5.0
>>> np.median(a) #中值
5.0
列表的拆分和合并
对于字符串,使用其split方法可以按指定的分隔符进行分割,分隔的结果以列表的形式返回。
下面给定一个字符串,使用split函数,用默认的空格分隔符进行分割,返回一个列表。
>>> a="大谦Excel dqexcel com"
>>> a.split()
['大谦Excel', 'dqexcel', 'com']
使用字符串对象的join方法可以用指定的间隔符连接列表给出的多个字符串。下面用变量b将要连接的字符串用列表给出,用变量a指定分隔符,连接列表各元素。
>>> a=','
>>> b=['大谦Excel', 'dqexcel', 'com']
>>> a.join(b)
'大谦Excel dqexcel com'
列表的过滤
过滤列表数据可以有多种方法,这里使用列表解析式和filter函数两种方式进行过滤。
下面创建一个列表a,元素为数字0-8。使用列表解析式过滤列表中大于3的数字,返回到列表b。
>>> a=range(9)
>>> b=[i for i in a if i>3]
>>> b
[4, 5, 6, 7, 8]
列表b中获取了列表a中大于3的元素。
下面使用filter函数进行过滤。该函数第1个参数设置过滤的条件表达式,第2个参数指定要过滤的列表。过滤的条件表达式用匿名函数指定列表a中的数字大于3。
>>> a=range(9)
>>> b=filter(lambda i:i>3,a)
>>> b
<filter object at 0x00000000031A5608>
filter函数返回的结果是一个filter对象,将它转换为列表。
>>> c=list(b)
>>> c
[4, 5, 6, 7, 8]
可见,列表c中获取了列表a中大于3的元素。
二维列表
可以通过列表嵌套创建二维或多维列表。二维列表有两层中括号,即列表的元素也是列表。下面创建一个二维列表:
>>> a=[[1,2,3],[4,5,6],[7,8,9]]
>>> a
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
对二维列表进行索引和切片时,要指定行维和列维两个方向上的索引号或取值范围。注意基数为0。
下面获取二维列表中第2行第3列元素的值:
>>> a[1][2]
6
对于二维列表的切片,我们首先要明白a[1]和a[1:2]之间的区别。a[1]获取的是二维列表a中的第2个元素,是一个一维列表,如下所示:
>>> a[1]
[4, 5, 6]
a[1:2]获取的则是一个二维列表,即
>>> a[1:2]
[[4, 5, 6]]
然后就比较好理解下面的结果:
>>> a[1][0]
4
>>> a[1:2][0]
[4, 5, 6]
以及
>>> a[1][0:1]
[4]
>>> a[1:2][0:1]
[[4, 5, 6]]
反复比较和理解这之间的差别。
Excel工作表与列表交换数据
Excel数据与Python列表之间的读写包括读取Excel数据到Python列表和将Python列表数据写入到Excel工作表。
一、读取Excel数据到Python列表
对于图7-9中工作表内的数据,将其中的行数据、列数据和区域数据读取到Python列表中。
图7-9 Excel数据
实现如下:
>>> import xlwings as xw
>>> bk=xw.Book()
>>> sht=bk.sheets(1)
>>> lst=sht.range('B2:D2';).value #行数据
>>> lst
[1.0, 2.0, 3.0]
>>> lst2=sht.range('B2:B4';).value #列数据
>>> lst2
[1.0, 4.0, 7.0]
>>> lst3=sht.range('B2:D4';).value #区域数据
>>> lst3
[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]
可见,工作表单元格区域中的行数据和列数据读取出来后都用一维列表保存,区域数据用二维列表保存。
将选项工具中expand参数的值设置为"table",可以将指定单元格扩展至它所在的区域。下面获取B2单元格所在区域的数据并保存到列表lst4中。
>>> lst4=sht.range('B2').options(expand='table').value
>>> lst4
[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]
二、将Python列表数据写入到Excel工作表
把列表数据写入到Excel工作表,指定区域的第1个单元格写入即可。下面把一维列表行数据写入到Excel工作表sht中。
>>> import xlwings as xw
>>> bk=xw.Book()
>>> sht=bk.sheets(1)
>>> lst=[1,2,3,4,5]
>>> sht.range('A1').value=lst #将Python数据写入Excel工作表
结果如图7-10所示。
图7-10 Python列表数据写入到Excel工作表
如果希望Python列表数据写入到Excel工作表中的某列,分两种情况,一种是列表数据是二维列数据,可直接写入;第二种是列表数据为一维行数据,写入的时候进行转置。
>>> import xlwings as xw
>>> bk=xw.Book()
>>> sht=bk.sheets(1)
>>> lst=[[1],[2],[3],[4],[5]]
>>> sht.range('C1').value=lst #直接写入
或
>>> import xlwings as xw
>>> bk=xw.Book()
>>> sht=bk.sheets(1)
>>> lst=[1,2,3,4,5]
>>> sht.range('E1').options(transpose=True).value=lst #转置
结果如图7-11所示。
图7-11 列数据写入到Excel工作表
将二维列表数据写入到Excel工作表区域中,指定目标区域左上角的单元格即可写入。
>>> sht.range('A1').value=[[1,2],[3,4]]
将单元格区域中的数据读取到二维数组。
>>> a=sht.range('A1:B2').value
>>> a
[[1.0, 2.0], [3.0, 4.0]]
数组示例-给定数据的简单统计
下面用Python列表解决7.1.12小节的问题。本示例的数据文件存放路径为Samples\ch07\Python\学生成绩统计.xlsx,py文件保存在相同目录下,文件名为sam07-01.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\学生成绩统计.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第1列数据最大行号
rows=sht.api.Range('A1').End(Direction.xlDown).Row
#计算各学生的总分
sc=[]
for i in range(2,rows+1):
#获取学生考分数据
lst=sht.range('B'+str(i)+':D'+str(i)).value
sc.append(sum(lst)) #求和,添加到列表
#在E列输出各学生总分
sht.range('E2').options(transpose=True).value=sc
#各科目的最高分和平均分
scc=sht.range('B2:B'+str(rows)).value #语文
scm=sht.range('C2:C'+str(rows)).value #数学
sce=sht.range('D2:D'+str(rows)).value #英语
sht.cells(2, 8).value=max(scc) #最高分
sht.cells(5, 8).value=sum(scc)/len(scc) #平均分
sht.cells(3, 8).value=max(scm)
sht.cells(6, 8).value=sum(scm)/len(scm)
sht.cells(4, 8).value=max(sce)
sht.cells(7, 8).value=sum(sce)/len(sce)
运行脚本,输出结果如图7-5所示。
数组示例-突出显示给定数据的重复值
下面用Python列表解决7.1.13小节的问题。本示例的数据文件存放路径为Samples\ch07\Python\突出显示重复值.xlsx,py文件保存在相同目录下,文件名为sam07-02.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\突出显示重复值.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第1列数据最大行号
row_num_1=sht.api.Range('A1').End(Direction.xlDown).Row
#工作表中第2列数据最大行号
row_num_2=sht.api.Range('B1').End(Direction.xlDown).Row
#第1列数据
data_1=sht.range('A2:A'+str(row_num_1)).value
#第2列数据
data_2=sht.range('B2:B'+str(row_num_2)).value
#遍历两列数据并进行比较
for i in range(row_num_2-2):
for j in range(row_num_1-2):
#如果有重复,亮显对应的单元格
if data_1[j]==data_2[i]:
sht.api.Cells(j+2,1).Interior.Color=\
xw.utils.rgb_to_int((0, 255, 255))
sht.api.Cells(i+2,2).Interior.Color=\
xw.utils.rgb_to_int((0, 255, 255))
运行脚本,输出结果如图7-6所示。
数组示例-求大于某数的最小值
下面用Python列表解决7.1.14小节的问题。本示例的数据文件存放路径为Samples\ch07\Python\求大于某数的最小值.xlsx,py文件保存在相同目录下,文件名为sam07-03.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\求大于某数的最小值.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#工作表中第1列数据最大行号
row_num_1=sht.api.Range('A2').End(Direction.xlDown).Row
#工作表中第2列数据最大行号
row_num_2=sht.api.Range('B2').End(Direction.xlDown).Row
#第2列数据
data_2=sht.range('B2:B'+str(row_num_2)).value
#从小到大排序
data_2_2=sorted(data_2)
#遍历两列数据并进行比较
for i in range(2,row_num_1+1):
for j in range(row_num_2-2):
#A列每个值与排序后的列表数据比较
#如果当前数据位于列表数据中两个相邻数据之间,取后者
data_1=sht.cells(i,1).value
if data_1>=data_2_2[j] and data_1<=data_2_2[j+1]:
sht.cells(i,3).value=data_2_2[j+1]
运行脚本,输出结果如图7-7所示。
数组示例-杨辉三角
下面用Python列表解决7.1.15小节的问题。本示例的数据文件存放路径为Samples\ch07\Python\杨辉三角.xlsx,py文件保存在相同目录下,文件名为sam07-04.py。
import xlwings as xw #导入xlwings包
#从constants类中导入Direction
from xlwings.constants import Direction
import os #导入os包
#获取本py文件的当前路径
root = os.getcwd()
#创建Excel应用,可见,没有工作簿
app=xw.App(visible=True, add_book=False)
#打开数据文件,可写
bk=app.books.open(fullname=root+\
r'\杨辉三角.xlsx',read_only=False)
sht=bk.sheets(1) #获取第1个工作表
#三角形所在矩形区域元素初始化为0,大小假设为5
tri=[]
for i in range(5):
tri.append([])
for j in range(5):
tri[i].append(0)
#计算杨辉三角中各元素的值
tri[0][0]=1 #三角形最上面点的值为1
for i in range(4):
tri[i+1][0]=1 #第1列的值都是1
tri[i+1][i+1]=1 #对角线边的值都是1
for i in range(4):
for j in range(4):
tri[i+1][j+1]=tri[i][j]+tri[i][j+1] #内部
#在工作表中输出杨辉三角
for i in range(5):
for j in range(5):
if tri[i][j]!=0:
sht.cells(i+2,j+2).value=tri[i][j]
运行脚本,输出结果如图7-8所示。