一、列表
1.二维列表
# 1.定义
list1 = [4,46,56,['abc','def']]
print(list1)
list2 = [[4,46],[56],['abc','def']]
print(list2)
# 2.访问元素
print(list1[0])
sublist = list1[-1]
print(sublist)
ele = sublist[0]
print(ele)
print(list1[-1][0])
# print(list2[1][1]) # IndexError: list index out of range
print(list2[1][0])
print(list2[2][1])
# 3.遍历列表
for sublist in list2:
for ele in sublist:
print(ele)
for i in range(len(list2)):
for j in range(len(list2[i])):
print(list2[i][j])
# 说明:关于容器之间的嵌套,后期使用较多的是列表嵌套列表 或者 列表嵌套字典
2.切片使用
什么是切片,请举例说明
切片:根据指定的区间,指定的步长,在列表,元组或字符串等有序集合中进行截取,形成一个新的列表,元组或字符串
语法: 列表名[start:end:step] start:开始索引,可以省略,默认为0,不省略的情况下包含在内 end:结束索引,可以省略,默认为索引的结束【len - 1 或 -len】,不省略的情况下不包含在内 step:表示步长,可以省略,默认为1
索引: 0 1 2 3 4 5 6 7 8 -9 -8 -7 -6 -5 -4 -3 -2 -1
注意:列表切片之后会得到一个新的列表,对原列表没有任何影响,相当于是列表的拷贝
"""
语法:
列表名[start:end:step]
start:开始索引,可以省略,默认为0,不省略的情况下包含在内
end:结束索引,可以省略,默认为索引的结束【len - 1 或 -len】,不省略的情况下不包含在内
step:表示步长,可以省略,默认为1
注意:
1.只要符合切片的语法,代码永远不会报错,只是结果列表是否为空
2.能获取到元素的前提下,只要step为负数,则表示逆序获取
"""
"""
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]
# 一、基本使用
# 1.省略start或end或step
# 注意1:start包含在内的,end如果定义出来不包含在内
print(numlist[1:]) # [1::1] [22, 33, 44, 55, 66, 77, 88, 99]
print(numlist[1:8]) # [22, 33, 44, 55, 66, 77, 88]
print(numlist[:6]) # [11, 22, 33, 44, 55, 66]
# 注意2:如果end超出索引的范围,默认取到结尾 *******【面试题】
print(numlist[1:100]) # [22, 33, 44, 55, 66, 77, 88, 99]
print(numlist[1:9]) # [22, 33, 44, 55, 66, 77, 88, 99]
# 注意3:numlist[:]表示将原列表拷贝了一份,经常用于一维列表的备份 *******
print(numlist[:])
print(numlist[::])
print(numlist[::1])
print(numlist[::2]) # [11, 33, 55, 77, 99]
list1 = [24,56,67,8]
print(list1)
list2 = list1[:]
list3 = list1
print(list2)
list1[1] = 100
print(list1) # [24, 100, 67, 8]
print(list2) # [24, 56, 67, 8]
print(list3) # [24, 100, 67, 8]
print("*" * 30)
# 2.start和end同正负
"""
规律1:如果start和end同正负
a.计算start+step
b.判断上述结果是否在start和end区间内
c.如果在区间内,则按照规律获取元素,如果不在区间内,则结果直接为[]
"""
# a.start和end都是正数索引
print(numlist[1:5:1]) # [22...55]
print(numlist[1:5:-1]) # []
print(numlist[5:1:1]) # []
print(numlist[5:1:-1]) # [66...33]
# b.start和end都是负数索引
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一个为正数,一个为负数
"""
规律2:start和end一个为正数,一个为负数
a.观察start的正负,索引的使用和start的正负保持一致
b.如果start为正,则使用正数索引;如果start为负,则使用负数索引
c.将end的索引转换为和start同符号的索引
d.继续使用规律1判断
"""
print(numlist[1:-5:1]) # [1:4:1] -----》[22...44]
print(numlist[1:-5:-1]) # [1:4:-1]---->[]
print(numlist[-1:5:1]) # [-1:-4:1]----->[]
print(numlist[-1:5:-1]) # [-1:-4:-1]---->[99...77]
print(numlist[-5:1:1]) # [-5:-8:1]----->[]
print(numlist[-5:1:-1]) # [-5:-8:-1]---->[55...33]
# 二、特殊情况
# 1.
"""
规律3:如果start和end都被省略
a.如果step为正数,则从左往右获取【顺序获取】
b.如果step为负数,则从右往左获取【逆序获取】
"""
print(numlist[::1])
print(numlist[::2])
print(numlist[::-1]) # ******* 倒序/反转
print(numlist[::-2])
# 2.
# print(numlist[100]) # IndexError
print(numlist[1:100]) #[22, 33, 44, 55, 66, 77, 88, 99]
print(numlist[100:]) # [] 面试题 *********
# 3.
print(numlist[0:-1:1]) # [0:8:1] ---->[11...88]
print(numlist[0:-1:-1]) # [0:8:-1]--->[]
print(numlist[-1:0:1]) # [-1:-9:1]---->[]
print(numlist[-1:0:-1]) # [-1:-9:-1] ----->[99...22]
# 4.
"""
规律4:列表[start::step]
a.如果step为正数,则从左往右获取【顺序获取】
b.如果step为负数,则从右往左获取【逆序获取】
"""
print(numlist[5::1])
print(numlist[5::-1])
print(numlist[-5::1])
print(numlist[-5::-1])
# 练习:
names = ['old_driver','rain','jack','shanshan','peiqi','black_girl']
# 取出names列表中索引4-7的元素
print(names[4:8])
# g.取出names列表中索引2-10的元素,步长为2
print(names[2:11:2])
# h.取出names列表中最后3个元素
print(names[-3:])
print(names[:2:-1])
3.列表中元素的删除
列表中元素的删除(经典例题--六种解法)
# 1.已知一个列表中保存的是学生的姓名,要求去掉重复的名字,
# 例如:names = ['张三', '李四', '大黄', '张三'] -> names = ['张三', '李四', '大黄']
names = ['张三', '李四', '大黄', '张三']
new_names = []
for name in names:
if name not in new_names:
new_names.append(name)
print(new_names)
# 2.删除一个列表中某个重复元素
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
for num in list1:
if num == 5:
list1.remove(5)
print(list1)
"""
分析:
原列表:[5,5,5,67,7,8,5,5,243,5,78,5]
第一次遍历:[5,5,67,7,8,5,5,243,5,78,5]
原因:因为遍历的是原列表,删除的也是原列表中的元素,当删除一个元素之后,列表会变短
,其中索引的体系会发生改变,但是for还是按照原来的方式在执行,所以导致某些元素"躲过"遍历
"""
# 方式一
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
i = 0
while i < len(list1):
print(i)
if list1[i] == 5:
list1.remove(5)
i -= 1
i += 1
print(list1)
# 方式二
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
for num in list1[:]:
if num == 5:
list1.remove(5)
print(list1)
# 方式三:
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
for num in list1.copy():
if num == 5:
list1.remove(5)
print(list1)
# 方式四:
import copy
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
for num in copy.copy(list1):
if num == 5:
list1.remove(5)
print(list1)
# 方式五:
list1 = [34,5,5,67,7,8,5,5,243,5,78,5]
for num in copy.deepcopy(list1):
if num == 5:
list1.remove(5)
print(list1)
二、简单算法
1.冒泡排序
排序思路:比较两个相邻的下标对应的元素,如果符合条件就交换位置(最值出现在最后位)
# 冒泡排序
# 以升序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
# 外层循环:控制的是比较的次数
for i in range(len(list1) - 1):
# 内层循环:控制的是每一轮比较的次数,同时兼顾参与比较的下标
for j in range(len(list1) - 1 - i):
# 比较:只要符合条件则交换位置
# 如果下标小的元素 > 下标大的元素 ,则交换位置
# 参与比较的下标,j 和j + 1
if list1[j] > list1[j + 1]:
list1[j],list1[j + 1] = list1[j + 1],list1[j]
print(list1)
# 降序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
# 外层循环:控制的是比较的次数
for i in range(len(list1) - 1):
# 内层循环:控制的是每一轮比较的次数,同时兼顾参与比较的下标
for j in range(len(list1) - 1 - i):
# 比较:只要符合条件则交换位置
# 如果下标小的元素 < 下标大的元素 ,则交换位置
# 参与比较的下标,j 和j + 1
if list1[j] < list1[j + 1]:
list1[j],list1[j + 1] = list1[j + 1],list1[j]
print(list1)
2.选择排序
排序思路:固定一个下标,然后拿这个下标对应的值依次和后面的元素进行比较,最值出现在头角标位置上
# 【面试题】选择排序
# 以升序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
# 外层循环:控制的是比较的轮数
for i in range(len(list1) - 1):
# 内层循环:控制的是每一轮比较的次数,兼顾参与比较的下标
for j in range(i + 1,len(list1)):
# 比较:只要符合条件则交换位置
# 如果下标小的元素 > 下标大的元素 ,则交换位置
# 参与比较的下标,i 和 j
if list1[i] > list1[j]:
list1[i],list1[j] = list1[j],list1[i]
print(list1)
# 以降序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
# 外层循环:控制的是比较的轮数
for i in range(len(list1) - 1):
# 内层循环:控制的是每一轮比较的次数,兼顾参与比较的下标
for j in range(i + 1,len(list1)):
# 比较:只要符合条件则交换位置
# 如果下标小的元素 < 下标大的元素 ,则交换位置
# 参与比较的下标,i 和 j
if list1[i] < list1[j]:
list1[i],list1[j] = list1[j],list1[i]
print(list1)
3.顺序查找
# 查找思路:将待查找元素和指定列表中的元素进行依次的比对,如果相等,则获取对应的索引即可
# 1.
list1 = [34,45,6,74,45,5,6,7,10,67]
key = 45
for i in range(len(list1)):
if list1[i] == key:
print(i)
print("*" * 30)
# 2.index():获取元素在列表中第一次出现的下标
list1 = [34,45,6,74,45,5,6,7,10,67]
key = 100
for i in range(len(list1)):
if list1[i] == key:
print(i)
break
else:
print(f"{key}在列表中不存在")
4.二分法查找
查找思路:如果列表是升序的前提下,将待查找的元素与中间下标对应的元素比较,如果大于中间下标对应的元素,则去右半部分查找
注意:前提是列表是有序(升序或者降序)的,通过折半来缩小查找范围,提高查找效率
# 二分法查找
# 以升序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
list1.sort()
# 待查找元素
key = 100
# 定义变量,分别表示索引的最大值和最小值
left = 0
right = len(list1) - 1
# left在逐渐增大,right在逐渐减小,在改变的过程中,知道left==right,还未找到指定元素,则说明该元素不存在
while left <= right:
# 计算中间下标
middle = (left + right) // 2
# 比较
if key > list1[middle]:
# 重置left的值
left = middle + 1
elif key < list1[middle]:
# 重置right的值
right = middle - 1
else:
print(f"待查找元素{key}在列表中的索引为:{middle}")
# 如果查找到,则可以提前结束循环,注意:只能获取一个索引
break
else:
print(f"{key}在列表中不存在")
# 以降序为例
list1 = [34,45,6,74,45,5,6,7,10,67]
list1.sort(reverse=True)
# 待查找元素
key = 100
# 定义变量,分别表示索引的最大值和最小值
left = 0
right = len(list1) - 1
# left在逐渐增大,right在逐渐减小,在改变的过程中,知道left==right,还未找到指定元素,则说明该元素不存在
while left <= right:
# 计算中间下标
middle = (left + right) // 2
# 比较
if key < list1[middle]:
# 重置left的值
left = middle + 1
elif key > list1[middle]:
# 重置right的值
right = middle - 1
else:
print(f"待查找元素{key}在列表中的索引为:{middle}")
# 如果查找到,则可以提前结束循环,注意:只能获取一个索引
break
else:
print(f"{key}在列表中不存在")