【保姆级入门系列】阿ken教你学Python(六) ——组合数据类型_组合数据类型中的转向用户重新选择

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

6.1.2 集合类型

🐮阿ken:数学中的集合是指具有某种特定性质的对象汇总而成的集体,其中构建集合的这些对象称为该集合的元素。例如,成年人集合的每一个元素都是已满18周岁的人。

通常用大写字母如 A、B、S……表示集合,用小写字母如 a、b、c……表示集合的元素。
集合中的元素具有 3个特征,具体如下。
(1) 确定性:给定一个集合,那么任何一个元素是否在集合中就确定了。例如,地球的四大洋构成一个集合,其内部的元素太平洋、大西洋、印度洋、北冰洋是确定的。
(2) 互异性:集合中的元素互不相同。
(3) 无序性:集合中的元素没有顺序,顺序不同但元素相同的集合可视为同一集合。Python 集合与数学中的集合概念一致,也具备以上 3个特性。 Python 要求放入集合中的元素必须是不可变类型,Python 中的整型、浮点型、字符串类型和元组属于不可变类型,列表、字典及集合本身都属于可变的数据类型。对于所有的数据类型而言,它们只要能进行哈希运算,就可以作为集合中的元素出现。关于集合的更多内容将在 6.4节讲解。

多学一招:哈希算法
哈希 (hash,散列)算法是将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈布值是原数据唯一且极其紧凑的数值表示形式,哪怕只更改原数据的一个字母,再次散列后产生的都是不同的值。若要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。

Python 提供了适用于哈希算法的函数hash(),该函数可以获取大多数数据 (如字符串、数字)的哈希值。例如:

hash("HeiMa")
1296313009587961352
hash("123456")
-8765639574853590066
hash("HeiMa123456")
9132461567425907503

由此看出,哈希值与哈希前的数据组合无关。

6.1.3 映射类型

在数学中,设 A、B是两个非空集合,若按某个确定的对应法则f,使集合 A中的任意一个元素 x,在集合 B中都有唯一确定的元素 y与之对应,则称 f为从集合 A到集合 B的一个映射。映射关系示例如下图所示:

映射类型也称作可变的哈希表 (散列表),哈希表是一种数据结构,表中存储存在映射关系的键值对,其中值为实际存储的数据,键为查找数据时使用的关键字。哈希表具有很好的査询性能,使用键可以快速地获取值。
Python 中同样采用 " 键-值 " 这种形式存储数据间的映射关系。字典是 Python唯一的内建映射类型,字典的键必须遵守以下两个原则:
(1) 每个键只能对应一个值,不允许同一个键在字典中重复出现。
(2) 字典中的键是不可变类型。                                                                        
关于字典的更多内容将在 6.5节讲解。

6.2 序列类型

6 2.1 切片

切片是指对序列截取其中一部分的操作。切片的语法格式如下:

[起始索引: 结束索引: 步长]

切片截取的范围属于左闭右开,即从起始索引开始,到结束索引前一位结束 (不句含结束位本身)。把索引比作一把 " 刀 “,在开始索引和结束索引的位置 " 切下 “,” 切下 " 的元素就是这个范围内的元素。步长的取值可以是正数和负数,默认值为1。                                   
根据步长的取值,可以分为如下两种情况:                                                                                     
(1) 步长大于 0                                                                                                                             
按照从左到右的顺序,每隔 " 步长-1 " (索引间的差值仍为步长值)个元素进行一次截取。这时,” 起始 " 指向的位置应该在 " 结束 " 指向的位置的左边,否则返回值为空。 
示例如下:

string = 'python' 
string[0:6] # 没指定步长,默认为1 
'python' 
string[2:5:2] # 指定步长为2 
'to' 

在上述示例中,如果没有指定步长默认为1。下面以 string[2:5:2] 为例,通过示意 图来分析切片的原理,如下图:

(2) 步长小于0                                                                                                                
按照从右到左的顺序,每隔“步长-1”(索引间的差值仍为步长值)个元素进行 一次截取。这时,“起始”指向的位置应该在“结束”指向的位置的右边,否则返回 值为空。 
示例如下:

string = 'python' 
string[3:0:-1] 
'hty' 
string[0:3:-2] 
''

注意,起始位置的索引必须大于结束位置的索引,否则返回空字符串。下面以 string[3:0:-1]为例,通过示意图来分析切片的原理,如下图所示。

6.2.2 列表

Python 列表是一个可变的序列,它没有长度的限制,可以包含任意个元素。列表的长度和元素都是可变的,开发人员可以自由地对列表中的数据进行各种操作,包括添加、删除、修改元素。
Python 列表的表现形式类似于其他语言中的数组,列表中的元素使用 " [ ] " 包含,各元素之间使用英文逗号分隔、例如:

 list_one = [] # 创建空列表
 list_one
 []
 list_two = [1, 10,55,20,6] # 列表元素的类型均是整型
 list_two
 [1, 10, 55, 20, 6]
 list_thr = [10, 'word', True, [6, 1]] # 列表中元素的类型不同
 list_thr
[10, 'word', True, [6, 1]]

通过 list()函数可以将已有的元组或字符串转换为列表,例如:

 words = 'Python'
 list(words) # 将字符串转换为列表
 ['P', 'y', 't', 'o', 'n']
 tuple_demo = (1, 3, 5, 7, 9)
 list(tuple_demo) # 将元组转换为列表
 [1, 3, 5, 7, 9]

使用循环可以对列表中的元素进行遍历操作,基本方式如下:

for 循环变量 in 列表:
语句块

例如,对列表 [‘P’, y, ‘t’, ‘h’, ‘o’, ‘n’], 执行遍历操作,具体示例如下:

for char in ['P', 'y', 't', 'h', 'o', 'n']: # 遍历列表的元素
print(char)
···
P
y
t
h
o
n

列表支持索引和切片操作。例如,操作列表 nums = [11, 22, 33] 中的元素,代码如下所示:

nums = [11, 22, 33]
nums[0] = 55 # 将列表中的索引为 0的元素修改为 55
nums
[55, 22, 33] # 使用[0,1]替换列表中索引为 0、1的元素
nums[0:2] = [0, 1]
nums
[0, 1, 33]
1ist1 = [5, 6]
nums += list1 # 将列表 list1中的元素追加到列表 nums中
nums
[0, 1, 33, 5, 6]

当使用一个列表的元素改变另一个列表的数据时,Python 并不要求两个列表长度相同,但是要遵循 " 多增少减 " 的原则,例如:

nums [1: 5] = [11, 7] # nums[1:5]的长度比[11,7]大
nums
[0, 11, 7]
nums[0:2] = [10, 5, 0] # nums[0:2]的长度比[10, 5, 0]小
nums
[10, 5, 0, 7]

以上代码的子序列 nums[1:5]中包含了 4个元素,使用 [11, 7]重新对其赋值时只给了两个元素,此时列表 nums的元素减少了 2个;同样,子序列 nums[0:2] 中包含 2个元素、使用 [10, 5, 0]重新对其赋值时给出了3个元素,此时列表 nums的元素增加了 1个。由此可知,使用一个列表给另一个列表赋值也可以实现列表的增加和删除操作。

Python 中常见的列表操作函数与方法具体如下表所示。

列表的常见操作

常见操作说明
len(s)计算序列 s的长度(元素个数)
min(s)返回序列 s中的最小元素
max(s)返回序列 s中的最大元素
list.append()在列表的末尾添加元素
list.extend()在列表中添加另一列表的元素,与 +=功能相同
list.insert(i)在列表索引为 i的元素之前插入元素
list.pop(i)取出并删除列表中索引为 i的元素
list.remove()删除列表中第一次出现的元素
list.reverse()将列表的元素反转
list.clear()删除列表中的所有元素
list.copy()生成新列表,并拷贝原列表中的所有元素
list.sort()将列表中的元素排序

多学一招: 列表和数组的区别
接触过其他语言 (比如C语言)的读者可能听说过数組这个类型。在很多編程
语言中都使用数组存储一组数据,而少数的编程语言采用列表这个类型。数组与列表
非常类似,但是并不完全一样,它们两个主要有以下区别。
(1) 数组在创建时需分配大小,它的大小是固定的,只能容纳有限的元素;列表无需预先分配大小,它可以在使用时动态地插入任意数量的元素。
(2) 数组和列表都可以存储任意类型的元素,但是数组要求元素的类型必须一致,也就是说所有元素要么都是数字类型,要么都是字符串或其它类型。列表则没有这个要求,它可以存储不同整数、浮点数、宇符串、甚至列表。

6.2.3 元组

Python 构建元组的方式非常简单,可以直接用圆括号包含多个使用逗号隔开的元素即可。非空元组的括号可以省略。创建元素的示例如下:

() # 创建一个空元组
()
1, # 由逗号结尾表示元组
(1, )
(1, ) # 单个元素的元组
(1, )
1, 2, 3 # 包含多个元素的元组
(1, 2, 3)
(1, 2, 3) # 包含多个元素的元组
(1, 2, 3)

通过 tuple()函数也可以构造元组,该函数的定义如下:

tuple(iterable)

tuple() 函数中的参数 iterable是一个可迭代( [dié dài] 意为更替。)的数据。使用 tuple()函数创建元组时,若没有传入任何参数,则创建的是一个空元组,例如:

tuple() # 创建空元组
()

使用 tuple()函数创建非空元组,具体示例如下:

tuple([1, 2, 4]) # 创建非空元组
(1, 2, 4)
tuple('python') # 创建非空元组
('p', 'y', 't', 'h', 'o', 'n')

元组类型在表达固定数据、函数多返回值、多变量同步赋值、循环遍历等情况下是十分有用的,例如:

def get_square(x):
···  return x, x*x # 函数返回多个值
···
x, y = 10, 20 # 多个变量同步赋值
x, y = (10, 20)
for x, y in((10, 20), (10, 25), (15, 25)): # 循环遍历元组
...  print(x, y)
···
10 20
10 25
15 25

6.3 实例 8:生成验证码

🐮**阿ken:**目前,很多网站都引入了验证码技术,以有效地防止用户利用机器人自动注册、登录、灌水、刷票、恶意破解密码等。验证码一般是包含一串随机产生的数字或符号、一些干扰元素 (如数条直线、若干圆点、背景图片等)的图片。用户使用肉限观察验证码、输入其中的数字或符号并提交给网站验证。

常见的 6位验证码示例如下:

kK64ul eOGpUz 3JfS81

以上验证码中每个字符可以是大写字母、小写字母或数字,有且只能是这三种类型的一种,具体生成哪种类型的宇符是随机的。本节将实现随机生成一组六位验证码的功能。
六位验证码功能需随机生成6个字符,将每个字符临时存储到某数据结构中。因此,本实例用到的数据结构需有可变、有顺序的特点,显然选用列表存储是最待合要求的。通过列表实现六位验证码功能的基本实现思路为:
(1) 创建一个空列表
(2) 生成 6个随机字符逐个添加到列表中。
(3) 将列表元素拼接成字符串。

以上思路中的步骤 (2)是验证码功能的核心部分,此部分主要实现生成 6个随机字符的功能。为确保每次生成的字符类型只能为大写字母、小写字母、数字的任一种,可使用 1、2、3分别代表这三种类型:若产生随机数1,表示生成大写字母;若产生随机数2,表示生成小写字母;若产生随机数3,表示生成数字。
除此之外,为确保每次生成的是大写字母、小写字母或数字类型中的字符,这里可根据数值范围或ACSII 码范围控制每个类型中包含的所有字符:数字对应的数值范围为 0~9;大写字母对应 ACSII码范围为 65 ~ 90;小写字母对应的 ACSII码范围为 97~122,之后再从这些字符中随机选择一个字符即可。
经过以上两次处理,便可以生成一个随机类型中的随机字符实现生成验证码功能的代码具体如下:

import random
code list = []
for 1 in range(6): # 控制验证码的位数
state random randint(1, 3) # 随机生成的字符分类
if state ==1
first kind random randint (65, 90) # 大写字母
random uppercase chr(first kind)
code list append(random uppercase)
elif state == 2:
second kinds= random randint(97,122) # 小写字母
random lowercase chr(second kinds
code list append (random lowercase)
elif state = 3:
third kinds =random, randint(0, 9) # 数字
code list append(str(third kinds)
verification code =mjoin(code list) # 将列表元素连接成字符串
print (verification code)

程序运行一次的结果为:

MbGLwX

6.4 集合类型

6.4.1 集合的常见操作

集合使用 “{ }” 包含元素,各个元素之间使用逗号进行分隔。创建集合最简单的方式是使用赋值语句例如:

set_demo = {100, 'word', 10.5} # 创建集合
set_demo
{'word', 10.5, 100}

上述集合定义时元素的顺序与打印时元素的顺序是不同的,说明集合中的元素是无序的。
还可以使用 set()函数进行创建集合,该函数中可以传入任何组合数据类型,例如:

set_one = set('tuple')
set_one
{'u', 't', 'e', 'l', 'p'}
set_two = set((13, 15, 17, 19))
set_two
{17, 19, 13, 15}

注意,空集合只能使用 set()函数进行创建。
集合是可变的数据类型,集合中的元素可以被动态地增加或删除。

集合的常见操作

常见操作说明
S.add(x)往集合 S中添加元素x(x不属于S)
S.remove(x)若x在集合S中,则删除该元素,不在则产生 KeyError异常
S.discard(x)若x在集合S中,则删除该元素,不在则不会报错
S.pop()随机返回集合 S中的一个元素,同时删除该元素。若 S为空,则产生 KeyError异常
S.clear()删除集合 S中的所有元素
S.copy()返回集合 S的一个副本
S.isdisjoint(T)若集合 S和 T中没有相同的元素,则返回True

假设有一个集合为 {10,151, 33, 98, 57},分别使用add()、remove()、pop()和 clear()方法给集合添加和删除元素,示例如下:

 set_demo=(10,151,3398,57) # 创建集合
 set_demo. add (61) # 向集合中添加元素61
 set_demo
 {33, 98, 10, 151, 57, 61}
 set_demo.remove(151) # 从集合中删除元素 151
 set_demo
 {33, 98, 10, 57, 61}
 set_demo.pop() # 从集合中随机删除一个元素
 set_demo
 {98, 10, 57, 61} # 删除集合中的所有元素
 set_demo.clear()
 set_demo
 set()

6.4.2 集合关系测试

数学中,两个集合关系的常见操作包括:交集、并集、差集、补集。设A,B是两个集合,集合关系的操作介绍如下。
(1) 交集是指属于集合 A且属于集合B的元素所组成的集合。
(2) 并集是指集合 A和集合 B的元素合并在一起组成的集合。
(3) 差集是指属于集合 A但不属于集合 B的元素所组成的集合。
(4) 补集是指属于集合 A 和集合 B但不同时属于两者的元素所组成的集合。
Python 中集合之间支持前面所介绍的 4种操作,操作逻辑与数学定义完全相同。
Python 提供了 4种操作符以实现这4项操作,分别是交集(&)、并集(|)、差集(-)、补集(^)。下面以两个圆形表示集合 A和 B,并使用阴影部分显示 4种操作的结果,

除此之外,Python还提供了 4个增强操作符 :|=、-=、&=、^=,它们与前面 4个操作符的区别是,前者是生成了 一一个新的集合,而后者是更新了位于操作符左侧的集合。接下来通过一张表罗列集合 S和 T之间关系的常见操作,

集合间的常见操作

常见操作说明
S/T S.union(T)返回一个新集合,该集合包含属于S和 T的所有元素
S-T S.difference(T)返回一个新集合,该集合包含属于集合 S但不属于集合 T的元素
S&T S.intersection(T)返回一个新集合,该集合包含同时属于集合 S 和 T的元素
S^T S.symmetric_difference(T)返回一个新集合,该集合包含集合 S和 T中的元素,但不包含同时属于两者的元素
Sl=T S.update(T)更新集合 S,该集合包含集合 S和 T所有的元素
S-=T S.difference_update(T)更新集合 S,该集合包含属于集合 S但不属于集合T的元素
S&=T S.intersection_update(T)更新集合 S,该集合包含同时属于集合 S和 T的元素
S^=T S.symmetric_difference_ update(T)更新集合S,该集合包含集合S和 T中的元素,但不包含同时属于两者的元素

假设有集合a={1, 11, 21, 31, 17}和集合b={0, 11, 20, 17, 30},它们执行取交集、并集、差集、补集的示例如下:

a={1, 11,21,31,17}
b={0,11,20,17,30}
a|b # 取a和b的并集
{0, 1, 11, 17, 20, 21, 30, 31}
a-b # 取a和b的差集
{1, 21, 31}
a&b # 取a和b的交集
{17, 11}
a^b # 取a和b的补集
{0, 1, 20, 21, 30, 31}

对于两个集合 A与 B,如果集合A中的所有元素都是集合B的元素,那么集合 B包含集合A,也就是说集合A是集合B的子集,集合B是集合A的超集;如果集合 A中的所有元素都是集合B中的元素,且集合B中至少有一个元素不属于集合 A,那么集合A是集合B的真子集,集合B是集合A的真超集。
Python 中使用的比较运算符可以用来检查某个集合是否为其他集合的子集或者超集,其中,“<”或者“<=”运算符用于判断真子集和子集,“>”和“>=”运算符用于判断的是真超集和超集。需要注意的是,“<”和“>”运算符支持的是严格意义定义的子集和超集,它们不允许两个集合相等;而“<=”和“>=”运算符支持的是非严格意义定义的子集和超集,它们允许两个集合是相等的。例如:

set_one = set('what')
set_two = set('hat')
set_one < set_two # 判断set_one是否为 set_two的严格子集
False
set_one > set_two # 判断set_one是否为set_two的严格超集
True

6.5 字典

6.5.1 字典类型介绍

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

等的。例如:

set_one = set('what')
set_two = set('hat')
set_one < set_two # 判断set_one是否为 set_two的严格子集
False
set_one > set_two # 判断set_one是否为set_two的严格超集
True

6.5 字典

6.5.1 字典类型介绍

[外链图片转存中…(img-TjUxx12U-1715709854177)]
[外链图片转存中…(img-f5clGVVn-1715709854178)]
[外链图片转存中…(img-Rx7q40CT-1715709854178)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值