小白如何成为python数据分析师
第8天---->列表的相关操作
列表------>:一种可变数据类型,也就是说列表可以添加元素、删除元素、更新元素。(可读可写的容器)使用
[]
字面量语法来定义列表。列表是容器,可以保存各种类型的数据,可以通过索引操作列表元素
1.定义:
在Python中,列表是由一系元素按特定顺序构成的数据序列,这样就意味着定义一个列表类型的变量,可以保存多个数据,而且允许有重复的数据。跟上一课我们讲到的字符串类型一样,列表也是一种结构化的、非标量类型,操作一个列表类型的变量,除了可以使用运算符还可以使用它的方法。
可以使用[]
字面量语法来定义列表,列表中的多个元素用逗号进行分隔,代码如下所示。
items1 = [5, 2, 0, 1, 3, 1, 4]
items2 = ['AI', 'R', 'Go', 'JAVA', 'Pyt']
除此以外,还可以通过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']
1.列表与元组、字符串相比较
列表是一种可变数据类型,也就是说列表可以添加元素、删除元素、更新元素,这一点跟我们上一课讲到的字符串有着鲜明的差别。字符串是一种不可变数据类型,也就是说对字符串做拼接、重复、转换大小写、修剪空格等操作的时候会产生新的字符串,原来的字符串并没有发生任何改变。
2.列表的相关操作
1.列表的生成
# 创建列表的方式一:字面量语法
list1 = ['apple', 'orange', 'durian']
print(list1)
# 创建列表的方式二:构造器语法
list2 = list(range(1, 10))
print(list2)
# 创建列表的方式三:生成式(推导式)语法
list3 = [i ** 2 for i in range(1, 10)]
print(list3)
强烈建议用生成式语法来创建列表”
2.列表的运算
列表支持拼接、重复、成员运算、索引和切片以及比较运算
1.拼接(合并)
list1 = [1, 3, 5, 7]
list2 = [4, 4, 8]
# 拼接(合并)
list1 = list1 + list2
list1 += list2
list1.extend(list2) # 拼接
print(list1)
2.重复
# 重复运算
list3 = [1, 10, 100] * 5
print(list3)
3.成员运算
# 成员运算 ---> in / not in ---> True / False---->在或者不在,返回布尔值
list4 = [1,3,5,8,'好']
print(10 in list4)
print(5 not in list4)
print('好' in list4)
print('不好' in list4)
4.索引和切片
# 切片
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print(items[:5]) # [1, 2, 3, 4, 5]
print(items[4:]) # [5, 6, 7, 8, 9, 10, 11]
print(items[-5:-7:-1]) # [7, 6]
print(items[::-2]) # [11, 9, 7, 5, 3, 1]
print(items[::-1]) #反转: [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
# 获取列表的长度(元素个数)
size = len(items3)
print(size) # 11
# 索引
print(items[0], items[-size]) # 1 1
items[-1] = 100 # 最后一个赋值为100
print(items[size - 1], items[-1]) # 100 100
5.比较运算
# 列表的比较运算
items5 = [1, 2, 3, 4]
items6 = list(range(1, 5))
# 两个列表比较相等性比的是对应索引位置上的元素是否相等
print(items5 == items6) # True
print(items5 == items6)
items7 = [3, 2, 1]
# 两个列表比较大小比的是对应索引位置上的元素的大小
print(items5 <= items7) # True
由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。对列表做索引操作一样要注意索引越界的问题,对于有
N
个元素的列表,正向索引的范围是0
到N-1
,负向索引的范围是-1
到-N
,如果超出这个范围,将引发IndexError
异常,错误信息为:list index out of range
。
3.列表元素的遍历
如果想逐个取出列表中的元素,可以使用for
循环的,有以下两种做法。
方法一:能读能写
items = ['Python', 'Java', 'Go', 'Kotlin']
for index in range(len(items)):
print(items[index])
方法二:只读不写(只能读取元素,元素不能做修改)
items = ['Python', 'Java', 'Go', 'Kotlin']
for item in items:
print(item)
3.列表的方法(执行的操作)
append------>在列表尾部添加元素
insert----->在列表指定索引位置插入元素
remove----->删除指定的元素
pop------>删除指定索引位置的元素
clear------>清空列表中的元素
del关键字后面跟要删除的元素
index---->查找元素位置
count----->查找元素出现的次数
sort----->排序(默认是从小到大排序,)
reverse
----->操作可以实现元素的反转
添加和删除元素
items = ['Python', 'Java', 'Go', 'Kotlin']
# 使用append方法在列表尾部添加元素
items.append('Swift')
print(items) # ['Python', 'Java', 'Go', 'Kotlin', 'Swift']
# 使用insert方法在列表指定索引位置插入元素
items.insert(2, 'SQL')
print(items) # ['Python', 'Java', 'SQL', 'Go', 'Kotlin', 'Swift']
# 删除指定的元素
items.remove('Java')
print(items) # ['Python', 'SQL', 'Go', 'Kotlin', 'Swift']
# 删除指定索引位置的元素
items.pop(0)
items.pop(len(items) - 1)
print(items) # ['SQL', 'Go', 'Kotlin']
# 清空列表中的元素
items.clear()
print(items) # []
使用Python中的del
关键字后面跟要删除的元素,
items = ['Python', 'Java', 'Go', 'Kotlin']
del items[1]
print(items) # ['Python', 'Go', 'Kotlin']
在使用
remove
方法删除元素时,如果要删除的元素并不在列表中,会引发ValueError
异常,错误消息是:list.remove(x): x not in list
。在使用pop
方法删除元素时,如果索引的值超出了范围,会引发IndexError
异常,错误消息是:pop index out of range
。使用Python中的
del
关键字后面跟要删除的元素,这种做法跟使用pop
方法指定索引删除元素没有实质性的区别,但后者会返回删除的元素,前者在性能上略优(del
对应字节码指令是DELETE_SUBSCR
,而pop
对应的字节码指令是CALL_METHOD
和POP_TOP
)。
元素位置和次数
1.查找位置
items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']
# 查找元素的索引位置
print(items.index('Python')) # 0
print(items.index('Python', 2)) # 5
# index('Python', 2):从下标为2开始查找python的位置。
# 注意:虽然列表中有'Java',但是从索引为3这个位置开始后面是没有'Java'的
print(items.index('Java', 3)) # ValueError: 'Java' is not in list
2.查找次数
items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']
# 查找元素出现的次数
print(items.count('Python')) # 2
print(items.count('Go')) # 1
print(items.count('Swfit')) # 0
3.元素排序和反转
列表的sort
操作可以实现列表元素的排序,而reverse
操作可以实现元素的反转,
items = ['Python', 'Java', 'Go', 'Kotlin', 'Python']
# 排序
items.sort() # 默认是从小到大排序,
items.sory(reverse=True) # 从大到小排序
print(items) # ['Go', 'Java', 'Kotlin', 'Python', 'Python']
# 反转
items.reverse()
print(items) # ['Python', 'Python', 'Kotlin', 'Java', 'Go']
4.嵌套列表
Python语言没有限定列表中的元素必须是相同的数据类型,也就是说一个列表中的元素可以任意的数据类型,当然也包括列表。如果列表中的元素又是列表,那么我们可以称之为嵌套的列表。
嵌套列表我们不能自己重复生成(*n),而是使用循环生成。不然在我们索引使用时就会出现一堆问题。嵌套的列表需要多次索引操作才能获取元素。
例如:
我们想保存5个学生3门课程的成绩,可以定义一个保存5个元素的列表保存5个学生的信息,而每个列表元素又是3个元素构成的列表,分别代表3门课程的成绩。
scores = [[0] * 3] * 5
print(scores) # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
看上去我们好像创建了一个5 * 3
的嵌套列表,但实际上当我们录入第一个学生的第一门成绩后,你就会发现问题来了,我们看看下面代码的输出。
# 嵌套的列表需要多次索引操作才能获取元素
scores[0][0] = 95 # 第一个列表中的第一个元素 = 95
print(scores) # [[95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0]]
创建嵌套列表的正确做法
scores = [[0] * 3 for _ in range(5)]
scores[0][0] = 95
print(scores) # [[95, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
练习
1.保存5个学生,3门课程的成绩,统计每个学生的平均成绩,统计每门课的最高分和最低分。
import random
names = ['A', 'B', 'C', 'D', 'E']
courses = ['语文', '数学', '英语']
# 随机生成成绩,嵌套循环,三门成绩,五个人的。
scores = [[random.randrange(50, 101) for _ in range(len(courses))]
for _ in range(len(names))
]
# 学生成绩
# 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, courses in enumerate(courses):
temp = [scores[i][j] for i in range(len(names))]
print(f'{courses}的最高分:{max(temp)}')
print(f'{courses}的最低分:{min(temp)}')
2.一个列表中有很多重复元素,写一段代码去掉列表中的重复元素。
# 方法1:计算元素个数,删除多的,
# 注意:删除时下标会混乱,建议反向删除。
nums = [12, 6, 6, 12, 12, 12, 14]
count = 0
for i in nums[::]: # 使用切片,循环切片内的元素,保证不影响列表下标。
# print(nums)
if nums.count(i) > 1:
nums.remove(i)
count += 1
# print(nums, count, i)
print(nums)
# 方法2.在空列表中添加没有的元素。
nums = [2, 5, 2, 4, 68, 12, 14]
unique_items = []
for i in nums:
if i not in unique_items: # 不在就加,在就不加。
unique_items.append(i)
print(unique_items)
删除所有相同元素
nums = [2, 5, 2, 4, 68, 12, 14]
for i in nums:
for j in nums:
if i == j:
nums.remove(i)
print(nums)
print()
3.用一个列表保存54张扑克牌,先洗牌,
再按斗地主的发牌方式把牌发给三个玩家,多的3张牌给第一个玩家(地主),
最后把每个玩家手上的牌显示出来。
# 循环发牌
import random
suites = ['♠︎', '♥︎', '♣︎', '♦︎']
faces = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
# 列表生成式(推导式)
cards = [f'{suite}{face}' for suite in suites for face in faces]
# append - 向列表中追加元素
cards.append('小王')
cards.append('大王')
# 随机乱序(洗牌)
random.shuffle(cards)
# 嵌套列表(列表中的元素又是列表)
players = [[] for _ in range(3)]
for _ in range(17):
for player in players:
# pop - 删除元素(默认删除最后一个元素)
player.append(cards.pop())
# extend - 将一个列表的元素合并到另一个列表中
players[0].extend(cards)
for player in players:
# sort - 对列表中的元素进行排序
player.sort(key=lambda x: x[1:])
for card in player:
print(card, end=' ')
print()
# 切片发牌
import random
INT = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
HS = ['梅花', '红桃', '方块', '黑桃']
nums = []
for i in INT:
for j in HS:
nums.append(i + j)
nums.append('大王')
nums.append('小王')
print(nums)
random.shuffle(nums)
A = nums[:17] + nums[51:]
print(f'地主拿到{len(A)}张:{A}')
B = nums[17:34]
print(f'农民B拿到{len(B)}张:{B}')
C = nums[34:51]
print(len(C))
print(f'农民C拿到{len(C)}张:{C}')
4.随机抽样
import random
nums = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
random.shuffle(nums) # 随机打乱
print(len(nums)) # 列表长度
print(random.sample(nums, 5)) # 无放回抽样
print(random.choices(nums, k=5)) # 有放回抽样,抽出列表。
print(random.choice(nums)) # 有放回抽样,抽一个元素