目录
定义和使用列表
- 在Python中,列表是由一系元素按特定顺序构成的数据序列,这样就意味着定义一个列表类型的变量,可以保存多个数据,而且允许有重复的数据。
- 跟上一课我们讲到的字符串类型一样,列表也是一种结构化的、非标量类型,操作一个列表类型的变量,除了可以使用运算符还可以使用它的方法。
items1 = [10,20,30,40,50,60]
items2 = [70,80,90]
- 在Python中,可以使用
[]
字面量语法来定义列表,列表中的多个元素用逗号进行分隔,代码如下所示。 - 除此以外,还可以通过Python内置的
list
函数将其他序列变成列表。准确的说,list
并不是一个函数,而是创建列表对象的构造器
items1 = list(range(1, 10))
print(items1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
items2 = list('hello')
print(items2) # ['h', 'e', 'l', 'l', 'o']
- 需要说明的是,列表是一种可变数据类型,也就是说列表可以添加元素、删除元素、更新元素,这一点跟我们上一课讲到的字符串有着鲜明的差别。字符串是一种不可变数据类型,也就是说对字符串做拼接、重复、转换大小写、修剪空格等操作的时候会产生新的字符串,原来的字符串并没有发生任何改变。
列表的运算符
- 和字符串类型一样,列表也支持拼接、重复、成员运算、索引和切片以及比较运算,对此我们不再进行赘述,请大家参考下面的代码。
items1 = [10,20,30,40,50,60]
items2 = [70,80,90]
print(f'items1:{items1},\nitems2:{items2}')
s1="1.列表的拼接"
print(s1.center(30,'*'))
items3=items1+items2
print(f'列表拼接items1=items2:{items3}')
s1="2.列表的重复"
print(s1.center(30,'*'))
items3+=items3
items5=items2*3
print(f'列表重复:items3+=items3:{items3},\nitems3*3:{items5}')
s1="3.列表的成员运算"
print(s1.center(30,'*'))
print(f'100是否在列表items1中:{100 in items1}')
print(f'80是否在列表items3中:{80 in items3}')
s1="4.获取列表元素长度(元素个数)"
print(s1.center(30,'*'))
size=len(items1)
print(f'items3:{items3}\nitems3的元素个数:{len(items3)}\n'
f'items2:{items2}\nitems2的元素个数:{len(items2)}')
print(f'items1:{items1},\nitems1的元素个数:{size}')
s1="5.列表的索引"
print(s1.center(30,'*'))
print(f'items1的第一个元素值:{items1[-size]}')
print(f'items2的第一个元素值:{items2[0]}')
print(f'items1的最后一个元素值:{items3[size-1]},{items1[-1]}')
s1="6.列表的切片"
print(s1.center(30,'*'))
print(f'items1的前五个:items1[:4]:{items1[:5]}')
print(f'items2的从第四个元素之后的元素:items2[4:]:{items2[4:]}')
print(f'items3从第三个元素开始间隔三个元素依次输出:items3[3::3]:{items3[3::3]}')
s1="7.列表的比较运算"
print(s1.center(30,'*'))
items5={"Spring","1010","abcd","白小鱼"}
items6={"Spring","1011","abc"}
items7={"abcd","白小鱼"}
items8={"Spring","1010","abcd","白小鱼"}
print(f"items5与items6是否相等:{items5==items6}")
print(f"items5>items7?:{items5>items7}")
print(f"items5与items8是否相等:{items5==items8}")
程序运行结果如下:
D:\装机软件\python\python.exe "D:/python code2020/untitled1/list.py"
items1:[10, 20, 30, 40, 50, 60],
items2:[70, 80, 90]
***********1.列表的拼接************
列表拼接items1=items2:[10, 20, 30, 40, 50, 60, 70, 80, 90]
***********2.列表的重复************
列表重复:items3+=items3:[10, 20, 30, 40, 50, 60, 70, 80, 90, 10, 20, 30, 40, 50, 60, 70, 80, 90],
items3*3:[70, 80, 90, 70, 80, 90, 70, 80, 90]
**********3.列表的成员运算***********
100是否在列表items1中:False
80是否在列表items3中:True
*******4.获取列表元素长度(元素个数)*******
items3:[10, 20, 30, 40, 50, 60, 70, 80, 90, 10, 20, 30, 40, 50, 60, 70, 80, 90]
items3的元素个数:18
items2:[70, 80, 90]
items2的元素个数:3
items1:[10, 20, 30, 40, 50, 60],
items1的元素个数:6
***********5.列表的索引************
items1的第一个元素值:10
items2的第一个元素值:70
items1的最后一个元素值:60,60
***********6.列表的切片************
items1的前五个:items1[:4]:[10, 20, 30, 40, 50]
items2的从第四个元素之后的元素:items2[4:]:[]
items3从第三个元素开始间隔三个元素依次输出:items3[3::3]:[40, 70, 10, 40, 70]
**********7.列表的比较运算***********
items5与items6是否相等:False
items5>items7?:True
items5与items8是否相等:True
Process finished with exit code 0
- 由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。
- 对列表做索引操作一样要注意索引越界的问题,对于有
N
个元素的列表,正向索引的范围是0
到N-1
,负向索引的范围是-1
到-N
,如果超出这个范围,将引发IndexError
异常,错误信息为:list index out of range
。 -
列表元素的遍历
- 如果想逐个取出列表中的元素,可以使用
for
循环的,有以下两种做法。items = ['Python', 'pluto', '卡戎', '白小鱼'] for index in range(len(items)): print(items[index]) items = ['java', '萌萌', '江火似流萤', 'Spring'] for item in items: print(item) D:\装机软件\python\python.exe "D:/python code2020/untitled1/b遍历.py" Python pluto 卡戎 白小鱼 java 萌萌 江火似流萤 Spring Process finished with exit code 0
“掷色子统计每个点数出现次数”的代码。
import random
将一颗色子掷6000次,统计每个点数出现的次数。这个任务对大家来说应该是非常简单的,我们可以用1到6均匀分布的随机数来模拟掷色子,然后用6个变量分别记录每个点数出现的次数,
import random
counters = [0] * 6#
print(counters)
for i in range(6000):#范围从1~6000
face = random.randint(1, 6)
counters[face - 1] += 1
for face in range(1, 7):
print(f'{face}点出现了{counters[face - 1]}次')
上面的代码中,我们用counters
列表中的六个元素分别表示1到6的点数出现的次数,最开始的时候六个元素的值都是0
。接下来用随机数模拟掷色子,如果摇出1点counters[0]
的值加1
,如果摇出2点counters[1]
的值加1
,以此类推。
列表的方法
和字符串一样,列表类型的方法也很多,下面为大家讲解比较重要的方法。
item=["生气","喜悦","嗔怒","清冷"]
print(f'item:{item}')
item.append("多情")#使用append方法在列表尾部添加元素
print(f'item:{item}')
item.insert(2,"悠然")#使用insert方法在列表指定索引位置插入元素
print(f'item:{item}')
item.remove("嗔怒")# 删除指定的元素
print(f'item:{item}')
item.pop(0)# 删除指定索引位置的元素
print(f'item:{item}')
# 清空列表中的元素
item.clear()
print(f'item:{item}')
D:\装机软件\python\python.exe "D:/python code2020/untitled1/y元素列表.py"
item:['生气', '喜悦', '嗔怒', '清冷']
item:['生气', '喜悦', '嗔怒', '清冷', '多情']
item:['生气', '喜悦', '悠然', '嗔怒', '清冷', '多情']
item:['生气', '喜悦', '悠然', '清冷', '多情']
item:['喜悦', '悠然', '清冷', '多情']
item:[]
Process finished with exit code 0
- 需要提醒大家,在使用
remove
方法删除元素时,如果要删除的元素并不在列表中,会引发ValueError
异常,错误消息是:list.remove(x): x not in list
。 - 在使用
pop
方法删除元素时,如果索引的值超出了范围,会引发IndexError
异常,错误消息是:pop index out of range
。 - 从列表中删除元素其实还有一种方式,就是使用Python中的
del
关键字后面跟要删除的元素,这种做法跟使用pop
方法指定索引删除元素没有实质性的区别, -
但后者会返回删除的元素,前者在性能上略优(item=["生气","喜悦","嗔怒","清冷"] del item[1] print(f'del :item:{item}') del :item:['生气', '嗔怒', '清冷']
del
对应字节码指令是DELETE_SUBSCR
,而pop
对应的字节码指令是CALL_METHOD
和POP_TOP
)。
元素位置和次数
列表类型的index
方法可以查找某个元素在列表中的索引位置;因为列表中允许有重复的元素,所以列表类型提供了count
方法来统计一个元素在列表中出现的次数。请看下面的代码。
tems = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']
# 查找元素的索引位置
print(items.index('Python')) # 0
print(items.index('Python', 2)) # 5
# 注意:虽然列表中有'Java',但是从索引为3这个位置开始后面是没有'Java'的
print(items.index('Java', 3)) # ValueError: 'Java' is not in list
items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']
# 查找元素出现的次数
print(items.count('Python')) # 2
print(items.count('Go')) # 1
print(items.count('Swfit')) # 0
元素排序和反转
列表的sort
操作可以实现列表元素的排序,而reverse
操作可以实现元素的反转,代码如下所示
。
item=["pluto","sunny","spring"]
print(item)
item.sort()
print(item)
item.reverse()
print(item)
['pluto', 'sunny', 'spring']
['pluto', 'spring', 'sunny']
['sunny', 'spring', 'pluto']
Process finished with exit code 0
列表的生成式
在Python中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。
下面是普通创建列表和生成式创建列表的两种方法结题对比:
print("1.生成1~9的数字列表")
item1=[]
for x in range(1,10):
item1.append(x)
print(item1)
item5=[x for x in range(1,10)]
print(item5)
print("2.创建一个由'hello world'中除空格和元音字母外的字符构成的列表")
item2=[]
for x in "hello world":
if x not in "aoeiu ":
item2.append(x)
print(item2)
item6=[x for x in 'hello world' if x not in "aoeiu "]
print(item6)
print("创建一个由个两个字符串中字符的笛卡尔积构成的列表")
items3 = []
for x in 'ABC':
for y in '123':
items3.append(x + y)
print(items3)
item7 = [x+y for x in "ABC" for y in "123"]
print(item7)
D:\装机软件\python\python.exe "D:/python code2020/untitled1/l列表的生产式.py"
1.生成1~9的数字列表
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2.创建一个由'hello world'中除空格和元音字母外的字符构成的列表
['h', 'l', 'l', 'w', 'r', 'l', 'd']
['h', 'l', 'l', 'w', 'r', 'l', 'd']
创建一个由个两个字符串中字符的笛卡尔积构成的列表
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
- 下面这种方式不仅代码简单优雅,而且性能也优于上面使用
for
循环和append
方法向空列表中追加元素的方式。 - 可以简单跟大家交待下为什么生成式拥有更好的性能,那是因为Python解释器的字节码指令中有专门针对生成式的指令(
LIST_APPEND
指令);而for
循环是通过方法调用(LOAD_METHOD
和CALL_METHOD
指令)的方式为列表添加元素,方法调用本身就是一个相对耗时的操作。 -
嵌套的列表
- Python语言没有限定列表中的元素必须是相同的数据类型,也就是说一个列表中的元素可以任意的数据类型,当然也包括列表。如果列表中的元素又是列表,那么我们可以称之为嵌套的列表。
- 嵌套的列表可以用来表示表格或数学上的矩阵,例如:我们想保存5个学生3门课程的成绩,可以定义一个保存5个元素的列表保存5个学生的信息,而每个列表元素又是3个元素构成的列表,分别代表3门课程的成绩。但是,一定要注意下面的代码是有问题的。
- 创建嵌套列表
- Python中的列表底层是一个可以动态扩容的数组,列表元素在内存中也是连续存储的,所以可以实现随机访问(通过一个有效的索引获取到对应的元素且操作时间与列表元素个数无关)
课程链接:https://github.com/jackfrued/Python-Core-50-Courses/blob/maste