Python学习日志05 - 元组

Python学习日志

RBHGO的主页欢迎关注

温馨提示:创作不易,如有转载,注明出处,感谢配合~

目录

第05课:Python的容器型数据类型-元组

前言

我们先通过一个题来补充上一课的嵌套的列表,这个知识。题目:用一个列表保存54张扑克牌,洗牌,按斗地主的发牌方式把牌发给三个玩家,剩下的3张底牌给第一个玩家(地主),把每个玩家手上的牌显示出来。在以下的应用中我推荐大家使用列表的生成式语法来创建列表,上一课中介绍过,它很好用,也是Python中非常有特色的语法。

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]
cards.append('小王')
cards.append('大王')
# 打乱牌组
random.shuffle(cards)

player_one = []
player_two = []
player_three = []
for _ in range(17):
    player_one. append(cards.pop())
    player_two.append(cards.pop())
    player_three.append(cards.pop( ))
player_one.extend(cards)
print(f'地主的手牌是{player_one}')
print(f'第一个农民的手牌是{[player_two]}')
print(f'第二个农民的手牌是{player_three}')

上面的代码可以实现我们的题目要求,但是我们好像又回到了了解分支、循环结构之前,做了很多重复的工作,特别时在建立玩家列表和发牌的时候。所以这里就引出来列表中嵌套的列表应该如何做。

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]
cards.append('小王')
cards.append('大王')

random.shuffle(cards)
# 嵌套列表(列表里的元素也是列表)
# players = [[], [], []]
# 只能用生成式语法循环结构,不能直接使用重复运算 players = [[]] * 3
# 重复运算的内部列表属于同一内存,赋值的时候不能单一问题这就会出现错误
players = [[] for _ in range(3)]

for _ in range(17):
    for player in players:
        player.append(cards.pop())
players[0].extend(cards)

for player in players:
    print(player)

学习了这种方法,我们再来做一个题,题目是“列表保存5个学生的3门学科的成绩,然后统计每个学生的平局成绩,统计每门课的最低分和最高分”。

import random

names = ['张三', '李四', '王二', '麻子', '大傻']
courses = ['语文', '数学', '英语']
# 通过生成式语法,得到一个含五个列表内涵3个元素为元素的列表
scores = [[random.randrange(50, 101) for _ in range(len(courses))]for _ in range(len(names))]
# 如果实在不习惯生成式语法也可以像下面这样做,直接赋值
# scores = [[100, 85, 80], [75, 99, 92], [73, 83, 60], [82, 79, 79], [69, 61, 59]]

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]) / len(courses):.2f}')

# 统计每门课的最低分和最高分
for j, course in enumerate(courses):
    temp = [scores[i][j] for i in range(len(names))]
    print(f'{course}的最高分是:{max(temp)}')
    print(f'{course}的最低分是:{min(temp)}')
进入正题

我在04课中和大家分享了Python中的列表,它是一种容器型数据类型,我们可以通过定义列表类型的变量来保存和操作多个元素。然后接下来我给大家分享另一种重要的容器型数据类型,它的名字叫元组(tuple)。

2.元组

在Python中,元组也是多个元素按照一定的顺序构成的序列。元组和列表的不同之处在于,元组是不可变类型,这就意味着元组类型的变量一旦定义,其中的元素不能再添加或删除,而且元素的值也不能进行修改。定义元组通常使用()字面量语法,也建议大家使用这种方式来创建元组。元组类型支持的运算符跟列表是一样。下面的代码演示了元组的定义和运算。

(1).创建元组
# 创建元组

# 空元组
a = ()
# 在创建一元组的时候,一定一定要记得逗号,否则就不是元组只是打了括号提升了优先级的整型、浮点型或字符串(也就是说不是元组)。
nums = (100)
fruits1 = ('peach',)
# type函数查看类型
print(type(nums))           # 运行结果 <class 'int'>
print(type(fruits1))        # 运行结果 <class 'tuple'>
# 定义了一个三元组
fruits2 = ('apple', 'pear', 'banana')
# 定义一个四元组
tup1 = ('RBHGO', 25, True, '慕尼黑')
(2).元组的运算符
# 重复运算
print(fruits1 * 3)          # 运行结果('peach', 'peach', 'peach')

# 成员运算
print('apple' in fruits1)
print('pear' in fruits2)

# 合并运算
fruits3 = fruits1 + fruits2
print(fruits3)              # 运行结果('peach', 'apple', 'pear', 'banana')
(3).元组的索引和切片
# 索引和切片
print(fruits3[3], fruits3[0])
print(fruits3[1:3])
print(fruits3[0:3:2])
# 元组的倒转
print(fruits3[::-1])                   # 运行结果 ('banana', 'pear', 'apple', 'peach')

# 找到元素在元组中的位置
print(fruits3.index('banana'))         # 运行结果 3
# 计算元素在元组中出现的次数
print(fruits3.count('banana'))         # 运行结果 1
(4).元组的应用

当我们把多个用逗号分隔的值赋给一个变量时,多个值会打包成一个元组类型;当我们把一个元组赋值给多个变量时,元组会解包成多个值然后分别赋给对应的变量,如下面的代码所示。

# 打包
a = 1, 10, 100
print(type(a), a)    # <class 'tuple'> (1, 10, 100)
  
# 解包
i, j, k = a
print(i, j, k)       # 1 10 100


# 多少个值对应多少个变量,如果数量不匹配均会报错
a, b, c = 1, 49, 568
print(a, b, c)           # 运行结果 1 49 568

# 如果硬要多值赋值给少变量,这时需要"*",加*号的变量会自己生成列表
d, *e, f = 1, 5, 9, 2, 21, 101
print(d, e, f)
                         # 运行结果 1 [5, 9, 2, 21] 101
# python内置ROT ---> rotate(旋转, 交替),所以可以这样用
a, b, c = d, e, f
print(a, b, c, d, e, f)  
                         # 运行结果 1 [5, 9, 2, 21] 101 1 [5, 9, 2, 21] 101

要说明的是,上面并没有用到打包和解包语法,Python的字节码指令中有ROT_TWOROT_THREE这样的指令可以实现这个操作,效率是非常高的。但是如果有多于三个变量的值要依次互换,这个时候没有直接可用的字节码指令,执行的原理就是我们上面讲解的打包和解包操作。

(5).元组和列表的比较

大家看到这,肯定有疑问,为什么有了列表还需要元组呢?列表不经可以读操作,还可以进行写操作,操作空间更大,肯定更有用,谁会用元组呢?当然!元组肯定有它的应用场景。

  1. 元组是不可变类型,不可变类型更适合多线程环境,因为它降低了并发访问变量的同步化开销。
  2. 元组是不可变类型,通常不可变类型在创建时间和占用空间上面都优于对应的可变类型, 也就是说创建一个列表的“花销”是大于创建一个元组。
  3. Python中的元组和列表是可以相互转换的,我们可以通过下面的代码来做到。
# 将元组转换成列表
info = ('RBHGO', 25, True, '慕尼黑')
print(list(info))       # ['RBHGO', 25, True, '慕尼黑']

# 将列表转换成元组
fruits = ['apple', 'banana', 'orange']
print(tuple(fruits))    # ('apple', 'banana', 'orange')

总结

列表和元组都是容器型的数据类型,即一个变量可以保存多个数据。列表是可变数据类型元组是不可变数据类型,所以列表添加元素、删除元素、清空、排序等方法对于元组来说是不成立的。但是列表和元组都可以进行拼接成员运算索引和切片这些操作,就如同之前讲到的字符串类型一样,因为字符串就是字符按一定顺序构成的序列,在这一点上三者并没有什么区别。

感谢学习陪伴,您的点赞,评论就是我更新的动力

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值