06-容器型数据类型-List
列表(list)
- 基本列表形式
nums = [1, 2, 3]
print(type(nums)) # list
# 常用以下方式对列表赋值
nums = [random.randrange(1, 1000) for _ in range(10)]
列表元素的插入、删除操作
- 在末尾插入一个元素
nums.append(4)
print(nums) # [1, 2, 3, 4]
- 在指定位置插入一个元素
nums.insert(0, 0)
print(nums) # [0, 1, 2, 3, 4]
- 删除最后一个元素
nums.pop()
print(nums) # [0, 1, 2, 3]
nums.pop(0) # 删除指定下标的元素
print(nums.pop(0)) # pop会返回删除的元素
- 删除指定元素
注意:remove只删除匹配的第一个元素
list3.remove(2)
列表的遍历
- 获取某个索引的指定元素
nums = [1, 2, 3, 4]
print(nums[0]) # 1
print(nums[-1]) # 4
- 遍历list中的所有元素
常用len()函数来获取列表中元素的个数,然后用for循环进行遍历
for i in range(len(nums)):
print(nums[i])
该方法可以简化,但此种方式只能进行读操作,无法改写元素的值
for num in nums:
print(num)
如果需要输出列表的index,可以使用enumerate函数
for i, x in enumerate(nums):
print(i, x)
例子1:将一个骰子投掷6万次,统计每一面的次数
import random
nums = [0, 0, 0, 0, 0, 0]
for _ in range(60000):
index = random.randrange(1, 7)
nums[index-1] += 1
for i, x in enumerate(nums):
print(f"{i+1}摇出了{x}次")
例子2:输入10个数字,计算方差、最大值、最小值、平均数
nums = []
for _ in range(10):
num = int(input("请输入数据:"))
nums.append(num)
ave_nums = sum(nums) / len(nums)
squ_sums = 0
for i in range(len(nums)):
squ_sums += (nums[i] - ave_nums) ** 2
var_num = squ_sums/len(nums)
max_num = max(nums)
min_num = min(nums)
print(f"最大值是:{max_num}")
print(f"最小值是{min_num}")
print(f"平均值是{min_num}")
print(f"方差是{squ_sums}")
例子3:输入三个数字,按从大到小输出
num1 = int(input("num1="))
num2 = int(input("num2="))
num3 = int(input("num3="))
if num1 < num2:
num1, num2 = num2, num1
if num1 < num3:
num1, num3 = num3, num1
if num2 < num3:
num2, num3 = num3, num2
print(num1, num2, num3)
例子4:列表添加10个随机整数,然后输出第二大的
import random
nums = []
for i in range(10):
nums.append(random.randrange(1, 1000))
for index in range(len(nums)):
for j in range(0, len(nums)-index - 1):
if nums[j] < nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
print(nums)
优化解法,用remove删掉最大值,剩下的max就是第二大的
import random
nums = []
for i in range(10):
nums.append(random.randrange(1, 1000))
print(nums)
nums.remove(max(nums))
print(max(nums))
优化解法,假定两个最大值是m1和m2,然后分别循环让元素和他们比较,如果存在比他们大的就进行交换。
import random
nums = []
for i in range(10):
nums.append(random.randrange(1, 1000))
m1, m2 = nums[0], nums[1]
if m1 > m2:
m1, m2 = m2, m1
for i in range(2, len(nums)):
if nums[i] > m1:
m1, m2 = nums[i], m1
elif nums[i] == m1: # 考虑到可能有重复数字的情况
pass
elif nums[i] > m2:
m2 = nums[i]
print(nums)
print(m1, m2)
列表的赋值
不建议用循环然后apped的方式,建议用推导式语法。运行效率高。
nums = [random.randrange(1, 1000) for _ in range(10)]
nums = [i ** 2 for i in range(1, 101, 2)] # 推导式语法,支持表达式
list1 = list(range(1, 101)) # 构造器语法
list2 = [1, 2, 3] # 字面语法
成员运算
可以检测一个元素是否存在列表里,返回布尔值
print(90 in nums)
print(100 not in nums)
列表的合并
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = list1 + list2
# list3 = list1.extend(list2) 效果是一样的
print(list3)
寻找某个元素
如果列表里没有该元素,则会报错。所以最后先判断列表中是否含有该元素。
if 3 in list3:
print(list3.index(3))
统计元素在列表中出现的次数
print(list3.count(2))
列表的翻转
nums = [1, 2, 3, 4, 5]
print(nums[::-1]) # 此种方式原列表没有改变,所以需要赋值给nums
nums = nums[::-1]
nums.reverse() # reverse方法会直接对列表本身进行翻转
列表的排序
items = [3, 1, 7, 0, 2]
items.sort() # 默认升序
items.sort(reverse=True) # 加上reverse可以变成降序
item.sort(key=int) # 按照整数逻辑排序
常用:列表中的元素转整数
生产环境中常见于导出来的数据是字符串类型的数字,可以用如下方法方便转换。
nums = ['1', '56', '20', '99', '234']
nums2 = [int(num) for num in nums]
排序算法1:min()法,简单选择排序
每次从剩下的元素中选择最小值,该算法效率较低
import random
nums = []
for i in range(10):
nums.append(random.randrange(1, 1000))
sort_nums = []
while len(nums)>0:
sort_nums.append(min(nums))
nums.remove(min(nums))
print(sort_nums)
优化
import random
nums = []
for i in range(10):
nums.append(random.randrange(1, 1000))
for i in range(len(nums)-1):
min_value, min_index = nums[i], i
# 假设第一个元素是最小的
for j in range(i+1, len(nums)):
if min_value > nums[j]:
min_value = nums[j]
min_index = j
nums[i], nums[min_index] = nums[min_index], nums[i]
# 每次循环都找到剩下元素中的最小值,然后和他交换
print(nums)
排序算法2:冒泡排序
for i in range(len(nums)):
for j in range(len(nums)-i-1):
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
print(nums)
优化:如果某一轮,一次交换都没有发生,说明排序已经完成,无需再循环下去了
for i in range(len(nums)):
swap = False
for j in range(len(nums)-i-1):
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
swap = True
if not swap:
break
print(nums)
优化2:搅拌排序
正向比较一遍,反向比较一遍。对于例子这样的数据,这样效率会很高。
nums = [9, 2, 3, 4, 5, 6, 1, 8]
for i in range(len(nums)):
swap = False
for j in range(len(nums)-i-1):
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
swap = True
if swap:
for k in range(j, 0, -1):
if nums[k] < nums[k - 1]:
nums[k], nums[k - 1] = nums[k - 1], nums[k]
else:
break
print(nums)
抽样
sample是无放回抽样,也就是说抽到的值不会重复
import random
nums = [i for i in range(100)]
select_nums = random.sample(nums, 5)
print(select_nums)
choices是放回抽样,抽到的值可能重复。然鹅即便如此,其实抽到重复概率也很小。
import random
nums = [i for i in range(100)]
select_nums = random.choices(nums, k=5)
print(select_nums)
# 用choice可以只抽一个元素
打乱顺序
random.shuffle(nums)
print(nums)
例子5:幸运女人(约瑟夫环)
15个男人和15个女人坐船出海,船坏了,需要把其中15个人扔到海里,其他人才能存活;
所有人围城一个圈,由某个人从1开始依次报数,报到9的人被扔到海里,下一个人重新开始从1报数,直到15个人都被扔进海里。最后,15个女人都活了下来,15个男人被扔到海里。
问原先哪些位置是男人,哪些位置是女人。
humans = [0] * 30
index, counter, number = 0, 0, 0
while counter < 15:
if humans[index] != 1:
number += 1
if number == 9:
humans[index] = 1
counter += 1
number = 0
if index == 29:
index = 0
else:
index += 1
for human in humans:
print("男" if human else "女", end="")
优化:每次去掉第九个,然后用9后面的,和前8个元素拼接新的列表,那么剩下的就全是女生了
humans = [i for i in range(1, 31)]
for _ in range(15):
humans = humans[9:] + humans[:8]
# 此时剩下的已经全是女的了
final_turns = [1] * 30
for i in range(len(humans)):
final_turns[humans[i]-1] = 0
for final_turn in final_turns:
print("男" if final_turn else "女", end="")
例子6:扑克牌
用一个列表保存54张扑克牌,先洗牌;
按照斗地主的发牌方式发给三个玩家,多的三张牌给第一个玩家(地主),
最后显示所有玩家的手牌。
import random
pokers = []
colors =["黑桃", "红心", "方块", "梅花"]
for color in colors:
for i in range(1, 14):
pokers.append(f"{color}{i}")
pokers.append("大王")
pokers.append("小王")
random.shuffle(pokers)
rich, poor1, poor2 = [], [], []
while len(pokers) > 3:
rich.append(pokers.pop())
poor1.append(pokers.pop())
poor2.append(pokers.pop())
rich += pokers
print(f"地主的牌:{rich}")
print(f"农民1的牌:{poor1}")
print(f"农民2的牌:{poor2}")
优化:生成牌的语句用以下一句即可
pokers = [f"{color}{i}"for color in colors for i in range(1, 14)]
优化2:以下语句可以把拿到的牌整理一下,相同数字放在一起
rich.sort(key=lambda x: x[2:])
嵌套列表
players由三个空的列表组成
players =[[] for _ in range(3)]
例子:保存学生的三科成绩
import random
names = ['a', 'b', 'c', 'd', 'e']
courses = ["语文", "数学", "英语"]
scores = [[random.randrange(50, 100) for _ in range(3)] for _ in range(5)]
for i, name in enumerate(names):
for j, course in enumerate(courses):
print(f"{name}的{course}分数是:{scores[i][j]}")
求平均分:
for i, name in enumerate(names):
print(f"{name}的平均分是:{sum(scores[i])/3:.1f}")
求各科的最高分:
for j, course in enumerate(courses):
temp = [scores[i][j] for i in range(len(names))]
print(f"{course}的最高分是:{max(temp)}")
例子:去掉列表中的重复元素
nums = [1, 1, 2, 3, 4, 5, 5, 5]
i = 0
while i < len(nums):
while nums.count(nums[i]) > 1:
nums.remove(nums[i])
i += 1
print(nums)