一、列表使用【重点掌握】(可改变)
1.概念
变量:使用变量存储数据,但是,缺点:一个普通的变量每次只能存储一个数据,num = 10 b = True
思考:如果一次性存储多个数据,怎么做?
实际问题:存储5个人的年龄,求他们的平均年龄,按照以前的方式解决:
age1 = 10
age2 = 18
age3 = 9
age4 = 15
age5 = 20
average = (age1 + age2 + age3 + age4 + age5) / 5
继续思考:如果要存储100,甚至1000个人的年龄呢?
解决方案:此时采用定义变量的方式会显得很麻烦,而Python提供了一种解决方案,使用列表进行多个数据的存储
作用:列表相当于是一个容器,可以同时存储多种类型的数据
【重点】本质:列表是一个有序的,可变的,可以存储重复元素的,可以同时存储不同类型的集合
说明:有序指的就是有顺序【数据的存放的顺序和底层存储的顺序是相同的】
2.基本使用
2.1定义列表
定义一个列表相当于定义一个列表类型的变量
变量名 = 值
语法:列表名 = [数据1,数据2,数据3…]
说明:
a.列表名其实就是一个变量名【标识符】,注意:尽量不要直接使用list【系统有一个功能list(x)】,使用listxxx
b.[]是列表特有的表示方式
c.数据1,数据2,数据3被称为元素element
d.列表中的元素会被自动编号,从0开始,该编号被称为索引,下标或者角标
e.索引的取值范围:0 ~ (元素个数 - 1)
-1 ~ -元素个数
# 1.空列表
l1 = []
print(l1)
print(type(l1))
# 2.非空列表
# 注意1:列表是有序的,数据的存放顺序和底层的存储顺序是一样的
l2 = [43,56,7,8,9]
print(l2)
# 注意2:列表中可以存储重复元素
l3 = [5,5,5,5,4,25,6]
print(l3)
# 注意3:列表中可以存储不同类型的数据
l4 = [34,False,'abc',45.78]
print(l4)
# 注意4:列表是可变的,所以一个列表被定义之后,就可以对列表的元素进行增删改的操作
l4[1] = 100
print(l4)
2.2列表元素访问
# 1.工作原理
# a.列表是有序的,所以可以通过索引访问元素
# b.变量中存储的是数据的地址,列表作为一个容器,其中存储的也是数据的地址,而非元素本身
# print(id(10))
# num = 10
# print(id(num))
# 2.获取列表中的元素
# 语法:列表[索引]
numlist = [12,34,54,5,6,78,8,100]
"""
正数:0 1 2 3 4 5 6 7 0~7
负数:-8 -7 -6 -5 -4 -3 -2 -1 -8~-1
元素:12 34 54 5 6 78 8 100
索引的取值范围:
a.0~(len - 1)
b.-len ~ -1
"""
# a.索引为正数
print(numlist[1])
print(numlist[7])
# print(numlist[8]) # IndexError: list index out of range
# b.索引为负数
print(numlist[-1])
print(numlist[-7])
# print(numlist[-9]) # IndexError: list index out of range
# 扩展:获取一个列表中元素的个数
print(len(numlist))
# 3.修改列表中的元素
# 语法:列表[索引] = 值
numlist = [12,34,54,5,6,78,8,100]
print(numlist,id(numlist))
numlist[1] = 888
print(numlist,id(numlist))
2.3列表基本操作
# 1.+:组合
l1 = [1,2,3]
l2 = [6,7,8]
print(l1 + l2) # [1, 2, 3, 6, 7, 8]
print(l2 + l1)
print(l1)
print(l2)
# 2.*
print(l1 * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
print(l1)
# 注意:+和*应用在列表中,都是生成了一个新的列表,并没有修改原列表
# 3.in和not in:判断指定的元素是否在指定的列表中,一般和if语句结合使用
numlist = [11,22,33]
print(11 in numlist) # True
print(11 not in numlist) # False
print(66 in numlist) # False
print(66 not in numlist) # True
二、列表
1.列表切片
"""
【面试题】什么是切片,请举例说明
切片:根据指定区间的索引,通过某种指定的规律,对列表,元组或字符串进行截取,形成一个新的列表,元组或字符串
语法:列表[start:end:step]
start:开始索引,可以省略,默认为0,不省略则包含在内
end:结束索引,可以省略,默认为最后一个【正数或负数】,不省略则不包含在内
step:步长,可以省略,默认为1
0 1 2 3 4 5 6 7 8
-9 -8 -7 -6 -5 -4 -3 -2 -1
11 22 33 44 55 66 77 88 99
注意:
a.只要切片的语法正确,哪怕获取不到任何元素,都不会报错,得到一个空列表
b.切片之后会得到一个新的列表,对原列表没有任何影响,类似于拷贝
"""
numlist = [11,22,33,44,55,66,77,88,99]
# 一、基本使用:规律
# 1.省略start或end或step
print(numlist[2:5]) # [33,44,55]
print(numlist[2:5:1]) # [33,44,55]
print(numlist[:5]) # [11,22,33,44,55]
print(numlist[0:5:1]) # [11,22,33,44,55]
print(numlist[2:]) # [33,44,55,66,77,88,99]
print(numlist[2:9:1]) # [33,44,55,66,77,88,99]
print(numlist[2:8:1]) # [33,44,55,66,77,88]
print("*" * 50)
# 2.start和end同正负
"""
0 1 2 3 4 5 6 7 8
-9 -8 -7 -6 -5 -4 -3 -2 -1
11 22 33 44 55 66 77 88 99
"""
numlist = [11,22,33,44,55,66,77,88,99]
"""
结论:如果start和end同正负,遵循下面的规律
a.就算start + step
b.判断上述结果是否在start和end区间内
c.如果存在,则按照规律依次获取,如果不存在,直接返回[]
"""
# a
print(numlist[1:5:1]) # [22,33,44,55]
print(numlist[1:5:-1]) # []
print(numlist[5:1:1]) # []
print(numlist[5:1:-1]) # [66,55....33]
# b
print(numlist[-1:-5:1]) # []
print(numlist[-1:-5:-1]) # [99...66]
print(numlist[-5:-1:1]) # [55...88]
print(numlist[-5:-1:-1]) # []
# 3.start和end一个为正,一个为负
"""
0 1 2 3 4 5 6 7 8
-9 -8 -7 -6 -5 -4 -3 -2 -1
11 22 33 44 55 66 77 88 99
"""
"""
结论:start和end一个为正,一个为负,遵循下面的规律
a.首先将start和end转化为同正负
如果start为正,end为负,使用正数索引
如果start为负,end为正,使用负数索引
b.就可以使用同正负的规律
"""
numlist = [11,22,33,44,55,66,77,88,99]
print(numlist[5:-1:1]) # [5:8:1]--->[66,77,88]
print(numlist[5:-1:-1]) # [5:8:-1]--->[]
print(numlist[-5:1:1]) # [-5:-8:1]--->[]
print(numlist[-5:1:-1]) # [-5:-8:-1]--->[55,44,33]
print(numlist[-1:5:1]) # [-1:-4:1]---->[]
print(numlist[-1:5:-1]) # [-1:-4:-1]--->[99...77]
print(numlist[1:-5:1]) # [1:4:1]---->[22...44]
print(numlist[1:-5:-1]) # [1:4:-1]---->[]
print("*" * 50)
# 二、特殊使用
# 1.
"""
结论:如果start和end都被省略,观察step的正负,
如果step为正数,则从左往右获取【顺序获取】
如果step为负数,则从右往左获取【逆序获取】
"""
print(numlist[::1]) # [11,22,33,44,55,66,77,88,99]
print(numlist[::2]) # [11,33....99]
print(numlist[::-1]) # [99,88.....11] *******
print(numlist[::-2]) # [99,77,....11]
# 2.
# print(numlist[100]) # 获取元素,IndexError
print(numlist[100:]) # []
# 3.
print(numlist[2:100]) # [33,44,55,66,77,88,99]
print(numlist[2:])
# 4.
print(numlist[0:-1]) # [11...88]
print(numlist[0:8]) # [11...88]
# 5.
print(numlist[-1:0:1]) # [-1:-9:1]--->[]
print(numlist[-1:0:-1]) # [-1:-9:-1]--->[99...22]
# 6.
"""
0 1 2 3 4 5 6 7 8
-9 -8 -7 -6 -5 -4 -3 -2 -1
11 22 33 44 55 66 77 88 99
"""
"""
结论:列表[start::step]
如果step为正数,则从左往右获取【顺序获取】
如果step为负数,则从右往左获取【逆序获取】
"""
print(numlist[5::1]) # [66....99]
print(numlist[5::-1]) # [66.....11]
print(numlist[-5::1]) # [55....99]
print(numlist[-5::-1]) # [55....11]
2.系统功能
函数 说明
len(list) 获取列表元素个数
max(list) 返回列表元素最大值
min(list) 返回列表元素最小值
list(seq) 将元组转换为列表
list.append(obj) 在列表末尾添加新的对象
list.count(obj) 统计某个元素在列表中出现的次数
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(seq) 从列表中找出某个值第一个匹配项的索引位置
list.insert(index,obj) 将对象插入列表
list.pop(index) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj) 移除列表中某个值的第一个匹配项
list.reverse() 反向列表中元素
list.sort(key=None,reverse=False) 对原列表进行排序
list.copy() 复制列表
list.clear() 清空列表
# print(dir(list))
# 一、增
# 1.append(x):追加,将任意类型的x追加到列表的末尾 *****
list1 = [1,2,3]
print(list1)
list1.append(10)
print(list1)
list1.append(False)
print(list1)
list1.append("abc")
print(list1)
list1.append([4,7])
print(list1)
print("*" * 50)
# 2.extend(x):扩展,通过容器x中的元素扩展列表,x只能是容器类型
# 可迭代对象【容器】:列表,字符串,元组,字典,集合,range()等
# 特点:只添加指定容器中的元素,不会添加容器本身,注意和append区分
list1 = [1,2,3]
print(list1)
# Extend list by appending elements from the iterable:通过容器中的元素扩展列表
list1.extend('abc')
print(list1)
list1.extend([4,7])
print(list1)
print("*" * 50)
# 3.insert(index,x):插入,在index的前面插入任意类型的x
list1 = [1,2,3]
print(list1)
# Insert object before index:在指定的索引之前插入数据
list1.insert(1,66)
print(list1)
list1.insert(2,'abc')
print(list1)
list1.insert(0,[4,7])
print(list1)
# 问题:在列表中,但凡涉及到列表元素的增加和删除,都是在原列表内部进行,所以,操作之后,只需要查看原列表即可
list1 = [1,2,3]
print(list1)
# r = list1.append(10)
# print(r) # None
list1.append(10)
print(list1) # [1,2,3,10]
print("*" * 50)
# 二、删
# 1.remove(x):移除,x表示需要被删除的元素 *******
# 特点:只会从左往右进行查找,删除第一次出现的元素
list1 = [11,5,3,5,7,8,5]
print(list1)
r = list1.remove(5)
print(list1)
print(r) # None
# list1.remove(10) # ValueError: list.remove(x): x not in list
# print(list1)
print("*" * 50)
# 2.pop(index):弹出,删除指定索引出的元素
# 特点:会移除指定索引的元素并将该元素返回,如果没有指定index,则移除并返回最后一个
list1 = [11,5,3,5,7,8,5]
print(list1)
# Remove and return item at index (default last)
r1 = list1.pop()
print(list1)
print(r1)
r2 = list1.pop(2)
print(list1)
print(r2)
# 3.clear():清除
list1 = [11,5,3,5,7,8,5]
print(list1)
list1.clear()
print(list1) # []
list1 = [11,5,3,5,7,8,5]
print(list1)
# del list1 # 删除列表
del list1[1] # 删除元素
print(list1)
# 三、改
# 1.reverse():逆序/倒序/反转 *******
list1 = [11,5,3,5,7,8,5]
print(list1)
list1.reverse() # 操作原列表
print(list1)
list1 = [11,5,3,5,7,8,5]
print(list1)
print(list1[::-1]) # 生成了一个新的列表
print(list1)
print("*" * 50)
# 2.sort()排序 ********
# a.升序
list1 = [11,5,3,5,7,8,5]
print(list1)
list1.sort()
print(list1)
# b.降序
list1 = [11,5,3,5,7,8,5]
print(list1)
list1.sort(reverse=True) # 先升序,然后反转
print(list1)
# sort并不是这么简单,也可以自定义排序规则,但是需要用到函数
# 四、查
list1 = [11,5,3,5,7,8,5]
# 1.len() ******
print(len(list1))
# 2.max()
print(max(list1))
# 3.min()
print(min(list1))
# 4.index():获取指定元素在列表中第一次出现的下标 *******
index1 = list1.index(5) # 默认全局查找
print(index1)
# list1 = [11,5,3,7,6,6,5,7,8,5]
# index2 = list1.index(5,2,6) # 在指定区间内查找,注意:包头不包尾
# 5.count():统计某个元素在列表中出现的次数
list1 = [11,5,3,7,6,6,5,7,8,5]
print(list1.count(6))
# 6.list()
print(list('abc'))
print(list((3,5,6)))
print(list(range(5)))
三、列表功能
1.列表遍历
# 遍历:依次获取一个容器中的所有元素
# 1.
list1 = ['a','b','c','d']
# print(list1[0])
# print(list1[1])
# print(list1[2])
# print(list1[3])
# 2.
i = 0
while i < len(list1):
print(list1[i])
i += 1
# 3.直接获取元素 *****
for ele in list1:
print(ele)
# 4.获取索引 ******
for n in range(len(list1)):
print(n,list1[n])
# 5.同时获取索引和元素
# print(enumerate(list1))
for i,ele in enumerate(list1):
print(i,ele)
# i,ele = (0, 'a')
2.练习
# 1.已知列表list1 = ['mon','sun','sat','fri','thu','wed'],list2 = ['sun','wed','thu'],
# 将属于list2的元素从list1中删除
list1 = ['mon','sun','sat','fri','thu','wed']
list2 = ['sun','wed','thu']
# 思路:将list2中的元素依次获取出来,然后判断在list1中是否存在,如果存在,则删除
for ele in list2:
if ele in list1:
list1.remove(ele)
print(list1)
# 2.统计101~200之间素数的个数,并且将所有的素数保存到列表中输出
# (素数又叫质数,就是只能被1和它本身整除的数),使用for循环实现
prime_list = []
# 外层循环:获取101~200之间的数
for num in range(101,201):
r = True
# 内层循环:判断一个是是否是质数
for i in range(2,num):
if num % i == 0:
r = False
break
if r:
prime_list.append(num)
print(len(prime_list),prime_list)
# 3.已知一个列表中保存的是学生的姓名,要求去掉重复的名字,
# 例如:names = ['张三', '李四', '大黄', '张三'] -> names = ['张三', '李四', '大黄']
# 思路:定义一个空列表,遍历旧列表,判断旧列表中的元素是否在新列表中,如果不存在,则添加,如果存在,则不添加
names = ['张三', '李四', '李四','李四','大黄', '张三']
new_names = []
for name in names:
if name not in new_names:
new_names.append(name)
print(new_names)
# 【面试题】4.已知列表list1 = [3,3,5,3,6,3,3,10],删除该列表中所有的3
# 方式一:切片,相当于拷贝
list1 = [3,3,5,3,6,3,3,10]
for num in list1[:]:
if num == 3:
list1.remove(num)
print(list1)
# 方式二:统计指定元素出现的次数
list1 = [3,3,5,3,6,3,3,10]
c = list1.count(3)
# 注意:如果for循环仅仅只为了控制次数,则可以将变量定义为_
for _ in range(c):
list1.remove(3)
print(list1)
# 方式三:append()
list1 = [3,3,5,3,6,3,3,10]
list2 = []
for num in list1:
if num != 3:
list2.append(num)
print(list2)
# 方式四:while 索引-1
list1 = [3,3,5,3,6,3,3,10]
i = 0
while i < len(list1):
if list1[i] == 3:
list1.remove(3)
i -= 1
i += 1
print(list1)
3.嵌套列表
# 1.一维列表
list1 = [4,7,8,9]
print(list1[1])
for n1 in list1:
print(n1)
# 2.多维列表
list2 = [[34,56,6],[1,5,6,7],[3,4]]
print(list2)
# a.访问元素
print(list2[1])
print(list2[1][1])
print(list2[-1])
print(list2[-1][-1])
# b.遍历
# 方式一
for sublist in list2:
for num in sublist:
print(num)
# 方式二
for i in range(len(list2)):
for j in range(len(list2[i])):
print(list2[i][j])
4.列表拷贝【面试题】
"""
变量中存储的是数据的地址
列表中存储的是数据的地址
例如:list1 = [11,22,33]
list1----->列表
list1[0]---->11
list1[1]---->22
list1[2]---->33
"""
# 一、引用赋值:=
# 1.一维列表
list1 = [11,22,33]
list2 = list1
print(id(list1),id(list2))
print(list1 is list2) # True
list1[1] = 100
print(list1 is list2) # True
print(list2) # [11,100,33]
# 2.二维列表
list1 = [[11,22,33],[44,55]]
list2 = list1
print(id(list1),id(list2))
print(list1 is list2) # True
list1[0][1] = 100
print(list1 is list2) # True
print(list2) # [[11,100,33],[44,55]]
"""
结论:列表使用=进行引用赋值,两个变量指向同一份内存地址
不管是几维列表,只要其中一个变量访问到的列表中的元素发生修改,则另一个变量访问的列表会随着修改
"""
print("*" * 50)
# 二、列表.copy()
# 1.一维列表
list1 = [11,22,33]
list2 = list1.copy()
print(id(list1),id(list2))
print(list1 is list2) # False
list1[1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [11,22,33]
# 2.二维列表
list1 = [[11,22,33],[44,55]]
list2 = list1.copy()
print(id(list1),id(list2))
print(list1 is list2) # False
list1[0][1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [[11,100,33],[44,55]]
print(id(list1[0]),id(list2[0]))
"""
结论:列表.copy()
一维列表:会将拷贝的列表开辟一份新的内存空间,所以其中一个列表中的元素修改,对另一个列表没有影响
二维列表:本质是一个浅拷贝,只会拷贝最外层的地址,所以如果其中一个列表修改内层列表中的元素,另一个列表会随着修改
"""
print("*" * 30)
# 三、copy.copy(列表)和copy.deepcopy(列表)
import copy
# 1.copy.copy()
# a.一维列表
list1 = [11,22,33]
list2 = copy.copy(list1)
print(id(list1),id(list2))
print(list1 is list2) # False
list1[1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [11,22,33]
# # b.二维列表
list1 = [[11,22,33],[44,55]]
list2 = copy.copy(list1)
print(id(list1),id(list2))
print(list1 is list2) # False
list1[0][1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [[11,100,33],[44,55]]
print("*" * 30)
# 2.copy.deepcopy()
# a.一维列表
list1 = [11,22,33]
list2 = copy.deepcopy(list1)
print(id(list1),id(list2))
print(list1 is list2) # False
list1[1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [11,22,33]
# b.二维列表
list1 = [[11,22,33],[44,55]]
list2 = copy.deepcopy(list1)
print(id(list1),id(list2))
print(list1 is list2) # False
list1[0][1] = 100
print(list1 is list2) # False
print(list1)
print(list2) # [[11,22,33],[44,55]]
"""
总结:
引用赋值:一个改,另一个随着改
浅拷贝:列表.copy() 或者 copy.copy(列表) 或者 切片,
特点:只会拷贝最外层,如果是多维列表,修改里层元素,对另一个列表有影响
深拷贝:copy.deepcopy()
特点:不管有几层,都会进行拷贝,所以修改一个列表中的元素,对另一个没有任何影响
"""
5.列表推导式
列表推导式,就是指的轻量级循环创建列表
# 列表推导式/列表生成式
# 语法:[元素的规律 for循环 if语句]
# 执行的顺序:for循环----》if语句----》元素的规律
# 1.生成一个列表[2,4,6,8,10]
# 方式一
list1 = list(range(2,11,2))
print(list1)
# 方式二
list2 = []
for i in range(2,11,2):
list2.append(i)
print(list2)
# 方式三
list3 = [i for i in range(2,11,2)]
print(list3)
# 2.生成一个列表[1,4,9,16,25]
# 方式一
list21 = []
for i in range(1,6):
list21.append(i ** 2)
print(list21)
# 方式二
list22 = [i ** 2 for i in range(1,6)]
print(list22)
# 3.生成一个列表[1,9,25,49,81]
list31 = [i ** 2 for i in range(1,10,2)]
print(list31)
list32 = [i ** 2 for i in range(1,10) if i % 2 != 0]
print(list32)
# 工作原理
list32 = []
for i in range(1,10):
if i % 2 != 0:
list32.append(i ** 2)
print(list32)
"""
优点:简化代码,可以快速的创建列表
缺点:只能实现简单的逻辑
"""