Python侧开28期-偕行-学习笔记-python数据结构

一、Python数据结构

1、数据类型

(1)Python3 中标准数据类型有:

  • 基本数据类型
    • Number(数字)
      • int整数
      • float浮点数(小数)
    • String(字符串)
    • bool(布尔类型)
  • 复合数据类型(容器类型)
    • List(列表)
    • Tuple(元组)
    • Dictionary(字典)
    • Set(集合)
  • 空类型
    • None

(2)Python3 根据数据的特性可分为:

  • 不可变数据(4 个):Number(数字)、bool(布尔)、String(字符串)、Tuple(元组);

  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合);

  • 有序数据(sequence):String(字符串)、Tuple(元组)、List(列表);

    • 索引:正索引(0,1,2,3…);负索引(…-3,-2,-1);
    • 切片:[start:end:step]默认step是1;
    • 拼接:有序数据都可以使用+(序列加法) *(序列乘法)进行拼接;
    • 通用方法:
      • len(obj):
      • manx(sequence);
      • min(sequence);
      • enumerate(sequence);
  • 元素唯一:Set(集合);

2、数据结构

(1)字符串操作

  • 注意 :所有的字符串操作,都不会影响原字符串本身,每次操作后都会得到一个操作后的新字符串对象;
  • 访问:索引、切片;
  • 特性:不可变对象;
  • 方法
    image
A、 统计查找替换类
  • 长度len(str) :用来获取参数字符串的字符个数,该函数并不是字符串类型特有的,而是一个通用函数,格式:len(obj)
length = len("Hello World")
print(length)
  • 统计个数count(str, start, end) :返回 strstring 里面出现的次数,如果 start 或者 end 指定则返回指定范围内 str 出现的次数,start是角标,从0开始,包左不包右“[ )”左闭右开区间
s = "ohello world python py"
print(s.count("py"))
print(s.count("o",0))# 4
print(s.count("o",1))# 3
print(s.count("o",4,8))
  • 查找索引index(sub, start, end) :检测 sub 是否包含在 string 中,如果 startend 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则抛出一个异常 ,格式:index(sub, start, end)
s = "ohello world python py"
print(s.index("o"))# 0
print(s.index("o",1))# 5
print(s.index("o",6,10))# 8
print(s.index("o",6,8))# ValueError: substring not found
  • 右侧查找索引rindex(sub, start, end):作用同 index() ,查找子串时从右侧查找,若找不到会抛出一个异常, 格式:rindex(sub, start, end)
s = "ohello world python py"
print(s.rindex("py"))# 20
print(s.rindex("py",10,15))# 13
print(s.rindex("py",15,19))# ValueError: substring not found
  • 查找索引find(sub, start, end): 检测 sub 是否包含在 string 中,如果 startend 指定范围,则检查是否包含在指定范围内,如果是返回开始索引值,否则返回-1 ,格式:find(sub, start, end)
s = "ohello world python py"
print(s.find("py"))# 13
print(s.find("java"))# -1
print(s.find("py",14,22))# 20

  • 右侧查找rfind(sub, start, end): 作用同 find() ,查找子串时从右侧查找,若找不到返回-1 ,格式:rfind(sub, start, end)
s = "ohello world python py"
print(s.rfind("py"))# 20
print(s.rfind("java"))# -1
print(s.rfind("py",10,20))# 13

  • 替换 replace(old, new, max): 把 string 中的 old 替换成 new,如果 max 指定,则替换不超过 max 次. 格式:replace(old, new, max)
s = "ohello world python py"
print(s.replace("o","-"))# -hell- w-rld pyth-n py
print(s.replace("o","-",3))# -hell- w-rld python py

B、 字符串判断类
  • 以XX开头startwith(prefix, start, end): 检查字符串是否是以 prefix 开头,是则返回 True,否则返回 False。如果 start 和 end 指定值,则在指定范围内检查;
url = "https://www.ceshiren.com"
print(url.startswith("https://"))# True
print(url.startswith("https://", 0, 3))# False
print(url.startswith("https://", 0, 7))# False
print(url.startswith("https://", 0, 8))# True
print(url.startswith("https://", 5, 30))# False
print(url.startswith("www", 8, 30))# True

  • 以xx结尾endwith(suffix, start, end):检查字符串是否是以 suffix 结尾,是则返回 True,否则返回 False。如果 start 和 end 指定值,则在指定范围内检查;
url = "https://www.ceshiren.com"
print(url.endswith("com"))# True
print(url.endswith(" "))# False
print(url.endswith("www",8,10))# False
print(url.endswith("www",8,11))# True

  • 全部都是字母isalpha() :如果 string 至少有一个字符并且所有字符都是字母或中文则返回 True, 否则返回 False;
print("abc".isalpha())# True
print("ABC".isalpha())# True
print("ABCabc".isalpha())# True
print("123".isalpha())# False
print("a b".isalpha())# False -- 空格不是字母
print("abc123".isalpha())# False
print("123abc".isalpha())# False
print("a@".isalpha())# False
print("".isalpha())# False --一个字符都没有
print("zhang三".isalpha())# True
print("张三".isalpha())# True
print("张三1".isalpha())# False

  • 全部都是数字isdigit(): 如果 string 只包含数字则返回 True 否则返回 False;
    • 注意:如何判断负数和浮点数字符串会返回False,因为此时string里面包含“-”和“.”这两个非数字的字符;
print("123".isdigit())# True
print("123abc".isdigit())# False
print("abc123".isdigit())# False
print("".isdigit())# False
print("-123".isdigit())# False
print("3.14".isdigit())# False

  • 全部都是字母或数字isalnum(): 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False;
print("abc".isalnum())# True
print("ABC".isalnum())# True
print("ABCabc".isalnum())# True
print("123".isalnum())# True
print("abc123".isalnum())# True
print("123abc".isalnum())# True
print("a b".isalnum())# False
print("a@".isalnum())# False
print("".isalnum())# False

  • 只包含空格isspace() 如果 string 中只包含空格,则返回 True,否则返回 False;
print(" ".isspace())# True
print("    ".isspace())# True
print("\t".isspace())# True --tab键,由4个空白组成
print("\n".isspace())# True
print("\r".isspace())# True
print("".isspace())# False
print(" a".isspace())# False
print("1 ".isspace())# False

  • 有字母并且全大写isupper() 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False;
print("ABC".isupper())# True
print("ABC123".isupper())# True
print("123ABC".isupper())# True
print("A!@#B".isupper())# True
print("abc".isupper())# False
print("abC".isupper())# False
print("abc123".isupper())# False
print("Abc!@#".isupper())# False
print("123".isupper())# False
print("".isupper())# False
print(" ".isupper())# False

  • 有字母并且全小写islower() 如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False;
print("abc".islower())
print("abc123".islower())
print("ABC".islower())
print("abC".islower())
print("Abc!@#".islower())
print("123".islower())
print("".islower())
print(" ".islower())

  • 必须只能每个单词首字母大写istitle() 如果 string 是标题化的(所有单词首字符是大写)则返回 True,否则返回 False;注意:使用符号“+ - _ 空格 点”连接组合不是一个单词,而是两个单词
print("Username".istitle())# True
print("username".istitle())# False
print("User+name".istitle())# False--两个单词
print("User+Name".istitle())# True--两个单词
print("User_Name".istitle())# True--两个单词
print("User_name".istitle())# False--两个单词
print("User.Name".istitle())# True--两个单词
print("User.name".istitle())# False--两个单词
print("UserName".istitle())# False ---username是一个单词,不是两个,所以只能要求首字母U大写
print("User Name".istitle())# True--两个单词
print("user name".istitle())# False--两个单词
print("User name".istitle())# False--两个单词

C、 字符串转换类
  • 串首字符转大写,其他转小写capitalize() 把字符串的第一个字符大写;
print("username".capitalize())# Username
print("Username".capitalize())# Username
print("userNAME".capitalize())# Username
print("this is username".capitalize())# This is username
print("123 this is username".capitalize())# 123 this is username
print("a123 this IS username".capitalize())# 123 this is username

  • 每个“单词”首字母转大写,其他转小写title() 返回"标题化"的 string,就是说所有单词都是以大写开始,其余字母均为小写;
print("this is username".title())# This Is Username
print("THIS IS USERNAME".title())# This Is Username
print("tHIS IS username".title())# This Is Username
print("123tHIS IS user456name".title())# 123This Is User456Name
print("12ab34cd".title())# 12Ab34Cd

  • 全部字母转大写upper() 转换 string 中的小写字母为大写;
print("abc".upper())
print("ABC".upper())
print("abCd".upper())
print("abc123".upper())
print("abc123ABC".upper())

  • 全部字母转小写lower() 转换 string 中的大写字母为小写;
print("abc".lower())
print("ABC".lower())
print("abCd".lower())
print("abc123".lower())
print("abc123ABC".lower())

D、 字符串对齐类
  • 居中,总长度width,不足部分fillchar填充center(width, fillchar) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串,如果指定fillchar参数,则使用指定字符填充,fillchar参数长度只能为1;
print("|"+"hogworts".center(20) + "|")# |      hogworts      | --总长度20,未指定填充字符,以空格填充
print("|"+"hogworts".center(5) + "|")# |hogworts| --总长度8,因为原串长度8,给定的5,原本已经居中,所以显示原串
print("|"+"hogworts".center(9) + "|")# | hogworts| --总长度9
print("|"+"hogworts".center(10) + "|")# | hogworts | --总长度10,不足部分空格填充
print("|"+"hogworts".center(20, "-") + "|")# |------hogworts------| --总长度20,不足部分-填充
print("hogworts".center(20, "-"))# ------hogworts------ --总长度20

  • 左对齐,总长度width,不足部分fillchar填充ljust(width, fillchar) 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串,如果指定fillchar参数,则使用指定字符填充,fillchar参数长度只能为1;
print("|"+"hogworts".ljust(20) + "|")# |hogworts            |
print("|"+"hogworts".ljust(5) + "|")# |hogworts|
print("|"+"hogworts".ljust(20, "-") + "|")# |hogworts------------|

  • 右对齐,总长度width,不足部分fillchar填充rjust(width, fillchar) 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串,如果指定fillchar参数,则使用指定字符填充,fillchar参数长度只能为1;
print("|"+"hogworts".rjust(20) + "|")# |            hogworts|
print("|"+"hogworts".rjust(5) + "|")# |hogworts|
print("|"+"hogworts".rjust(20, "-") + "|")# |------------hogworts|

E、 字符串去除空白类
  • 去除左右两侧指定“字符”strip(chars) 删除 string 左右两侧的空白字符, 如果指定chars参数,则删除左右两侧指定的字符;
print("|" + "  hogworts  " + "|")# |  hogworts  |
print("|" + "  hogworts  ".strip() + "|")# |hogworts| --不给参数,去掉两侧空格
print("|" + "  hogworts".strip() + "|")# |hogworts|--不给参数,去掉两侧空格,右侧没有空格,所以去掉左侧即可
print("|" + "hogworts  ".strip() + "|")# |hogworts|--不给参数,去掉两侧空格,左侧没有空格,所以去掉右侧即可
print("|" + "  h o g w o r t s  ".strip() + "|")# |h o g w o r t s| --只去掉两侧,中间的不管
print("|" + "bachogwortsabc".strip("cbas") + "|")# |hogwort| --左侧去掉bac,右侧去掉sabc
print("|" + "bachogwortsabc".strip("c") + "|")# |bachogwortsab| --左侧没有c,去掉右侧c

  • 去除左侧指定“字符”lstrip(chars) lstrip() 删除 string 左边的空白字符, 如果指定chars参数,则删除左两侧指定的字符;
print("|" + "  hogworts  " + "|")
print("|" + "  hogworts  ".lstrip() + "|")# |hogworts  |
print("|" + "  hogworts".lstrip() + "|")# |hogworts|
print("|" + "hogworts  ".lstrip() + "|")# |hogworts  |
print("|" + "  h o g w o r t s  ".lstrip() + "|")# |h o g w o r t s  |
print("|" + "bachogwortsabc".lstrip("cba") + "|")# |hogwortsabc|

  • 去除右侧指定“字符”rstrip(chars) rstrip() 删除 string 左边的空白字符, 如果指定chars参数,则删除右两侧指定的字符;
print("|" + "  hogworts  " + "|")
print("|" + "  hogworts  ".rstrip() + "|")# |  hogworts|
print("|" + "  hogworts".rstrip() + "|")# |  hogworts|
print("|" + "hogworts  ".rstrip() + "|")# |hogworts|
print("|" + "  h o g w o r t s  ".rstrip() + "|")# |  h o g w o r t s|
print("|" + "bachogwortsabc".rstrip("cba") + "|")# |bachogworts|

F、 字符串分割类
  • 以sep分割maxsplit次 split(sep, maxsplit) 以 sep 为分隔符分割 string,如果指定 maxsplit 参数,则仅分割 maxsplit次;结果为列表
print("a-b-c-d".split("-"))# ['a', 'b', 'c', 'd']
print("a-b-c-d".split("-", 2))# ['a', 'b', 'c-d']
print("a--b-c-d".split("-"))# ['a', '', 'b', 'c', 'd']
print("a-+b-c-d".split("-+"))# ['a', 'b-c-d']
print("a b\tc\nd\re".split())# ['a', 'b', 'c', 'd', 'e']
print("a b c d e".split(" ", 3))# ['a', 'b', 'c', 'd e']


  • 以换行符分割splitlines(keepends) 使用换行符\n 分割 string,如果指定 keepends 参数,则结果中会保留\n 符号;结果为列表
print("a\nb\nc".splitlines())# ['a', 'b', 'c']
print("a\nb\nc".splitlines(True))# ['a\n', 'b\n', 'c'] --以换行符分割并且保留了换行符

  • 以sep 分割为三元素的元组parttion(sep) 从 sep 出现的第一个位置起,把 string 分成一个3元素的元组(string_pre_sep,sep,string_post_sep),如果 string 中不包含 sep 则 string_pre_str == string,其余元素为空字符串;
print("This is Hogworts".partition("is"))# ('Th', 'is', ' is Hogworts')
print("This is Hogworts".partition("iss"))# ('This is Hogworts', '', '')

  • 从右 以sep 分割为三元素的元组rparttion(sep) 从右向左 sep 出现的第一个位置起,把 string 分成一个3元素的元组 (string_pre_sep,sep,string_post_sep),如果 string 中不包含 sep 则 string_post_str == string,其余元素为空字符串;
print("This is Hogworts".rpartition("is"))# ('This ', 'is', ' Hogworts')
print("This is Hogworts".rpartition("iss"))# ('', '', 'This is Hogworts')

G、 字符串连接类
  • +号 将两个字符串连接生成一个新字符串, + 号两侧必须都是字符串, 格式:str1 + str2
print("Hello" + "World")
print("Hello" + "123")
print("Hello" + 123)

  • *号 将字符串重复N次后生成一个新字符串 格式:str * n
print("*"* 10)
print("hello"* 10)

  • join(iterable) 使用 string 连接可迭代对象中的所有元素,可迭代对象参数中的所有元素必须是字符串;
print("".join(("a","b","c")))# abc --字符串元组
print("-".join(("a","b","c")))# a-b-c --字符串元组
print("->".join(("a","b","c")))# a->b->c --字符串元组
print("->".join(["a","b","c"]))# a->b->c --字符串列表
print("->".join({"a","b","c"}))# c->a->b --字符串集合,反向
print("->".join({"a":"A","b":"B","c":"C"}))# a->b->c --字符串字典,只取了键

H、 编码解码类
  • 编码encode(encoding) 使用 encoding 指定的字符集,对 string 进行编码,转换成二进制字符串;
print("abc123".encode("gbk"))# b'abc123'
print("你好".encode("gbk"))# b'\xc4\xe3\xba\xc3'
print("abc123".encode("utf-8"))# b'abc123'
print("你好".encode("u8"))# b'\xe4\xbd\xa0\xe5\xa5\xbd'

  • 解码decode(encoding) 使用 encoding 指定的字符集,对 string 进行解码,转换成字符串对象, string必须是二进制字符串;
s1 = b'\xc4\xe3\xba\xc3'
s2 = b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(s1.decode("gbk"))# 你好 --print("你好".encode("gbk"))# b'\xc4\xe3\xba\xc3'
print(s2.decode("utf-8"))# 你好

print(s1.decode("gbk"))# 你好 
print(s2.decode("u8"))# 你好 --print("你好".encode("u8"))# b'\xe4\xbd\xa0\xe5\xa5\xbd'
I、 切片操作
  • str[start: end: step]对字符串按指定的范围进行截取,得到一个子字符串,指定范围时,起始下标必须小于结束下标,且子字符串不包含结束下标;
s = "abcdefg"

# 普通切片
print(s[0: 2])# ab
# 省略范围
print(s[0:])# abcdefg
print(s[: 2])# ab
print(s[:])# abcdefg
# 指定步长
print(s[::1])# abcdefg
print(s[::2])# aceg
# 负下标
# -7 -6 -5 -4 -3 -2 -1  
#  a  b  c  d  e  f  g
print(s[-3: -1])# ef 
# 负步长
print(s[-1: -3: -1])# gf
# 逆序
print(s[::-1])# gfedcba

(2)元组

A、元组的特点

  • 元组是有序的数据结构,这意味着元组中的元素按照它们的顺序存储,并且可以通过索引进行访问和引用。这意味着元组中的元素保持其原始顺序,不会发生改变。

  • 元组是不可变的,一旦定义后,元组中的数据不可以进行添加,修改和删除等操作。

    • 元组的不可变性使其在某些情况下很有用,例如在需要确保数据的完整性和不变性的场景中。它们也可以用作字典的键或作为函数的参数和返回值。
  • 元组是异构的,可以包含不同类型的元素,例如整数、浮点数、字符串等。这使得元组成为一种有效的数据结构,用于存储多种不同类型的元素。

B、元组的定义

a、元组的字面量定义
  • 元组使用小括号 () 来定义,将元组中的元素括在小括号中。
  • 元组中的元素通过逗号 , 进行分隔,每个元素都可以是不同的数据类型。
  • 使用小括号 () 来创建一个空元组。如果没有任何元素需要添加到元组中,空元组没有任何实际意义。
  • 定义元组时,逗号是必须的,即使元组只包含一个元素,也需要在元素后面加上逗号,以区分它是一个元组而不是其他数据类型。
t1 = (1, 2, "hello", True)
t2 = (1, )
t3 = (1)
t4 = ()
print(type(t1))
print(type(t2))
print(type(t3))
print(type(t4))
t5 = 1
print(t3 == t5)
print(t3 is t5)
***********************
<class 'tuple'>
<class 'tuple'>
<class 'int'>
<class 'tuple'>
True
True
  • 注意:变量赋多个值得到的也是元组,这是python的组包操作
t = 1,"hello"
print(t)# (1,"hello")
b、 元组的构造方法定义
  • 当使用构造方法定义元组时,参数只能是可迭代的对象,构造方法会将参数中的元素构造成为元组的元素。 可以理解为将可迭代的对象强制类型转换为元组
t1 = tuple("abc")
t2 = tuple((1,2,3))
t3 = tuple(((1,2,3),(4,5)))
t4 = tuple([1,2,3])
t5 = tuple(([1,2,3],(6,7)))
t6 = tuple(([1,2,3],[8,9]))
print(t1)
print(t2)
print(t3)
print(t4)
print(t5)
print(t6)
**************************
('a', 'b', 'c')
(1, 2, 3)
((1, 2, 3), (4, 5))
(1, 2, 3)
([1, 2, 3], (6, 7))
([1, 2, 3], [8, 9])

C、 元组中元素的引用

  • 元组同字符串一样,也可以使用下标形式引用元组中的元素。并且,下标不能超过元组的元素个数减1,否则会抛出下标越界错误。
t = (1,2,3,4,5)
print(t[0])# 1
print(t[3])# 4
print(t[5])# IndexError: tuple index out of range

D、元组的切片操作

  • 元组的切片操作同字符串一致,[start,end,tep];
t = (1,2,3,4,5)
print(t[0:3])# (1, 2, 3)
print(t[:3])# (1, 2, 3)
print(t[3:])# (4, 5)
print(t[:])# (1, 2, 3, 4, 5)
# 逆序
print(t[::-1])# (5, 4, 3, 2, 1)

E、元组的应用场景

  • 存储一组不可变的数据:由于元组的不可变性,它们非常适合存储一组不会发生变化的数据,如常量、配置信息等。您可以使用元组来存储相关的值,以确保数据的完整性和不变性。
  • 作为字典的键:元组可以作为字典的键使用,因为元组是不可变的,可以保证字典中的键的稳定性。相比列表,元组更适合作为字典的键,因为字典的键必须是不可变的。
  • 函数返回多个值:函数可以使用元组作为返回值,以便一次性返回多个相关的值。通过返回元组,函数可以将多个数据打包在一起,并且调用函数时可以方便地解包元组,获取其中的各个值。

F、元组的常用方法

  • 由于元组的不可变特性,所以元组提供的操作方法非常少。
  • 元组的长度len(t) 获取元组元素个数;
  • value的个数count(value) 统计元组中参数 value 指定值的个数;
t = (1,2,3,4,5,1,2,3,1,2,3,3,3,3)
print(t.count(3))# 6

  • value第一次出现的下标index(value, start,stop) 在元组中查找 value 第一次出现的下标。如果指定了范围,则仅在指定范围内查找,如果查找的数据在元组中不存在,会抛出一个错误;
t = (1,2,3,4,5,1,2,3)
print(t.index(3))# 2
print(t.index(3, 5,10))# 7
print(t.index(0))# ValueError: tuple.index(x): x not in tuple

(3)列表

  • 特点:
    • 有序性:列表中的元素按照添加的顺序进行存储,每个元素都有一个对应的索引,可以通过索引访问和操作列表中的元素。
    • 可变性:列表是可变的,也就是说可以通过索引来修改、删除或插入元素。可以改变列表的长度、内容和顺序。
    • 异构:列表中可以同时存储不同类型的数据,例如整数、字符串、浮点数、布尔值等。甚至可以存储其他列表或其他复杂的数据结构。

A、列表的定义

a、字面量定义
l1 = []  # 创建一个空列表
l2 = [1, 2, 3, "hello", True]  # 创建一个包含多个元素的列表
b、 列表的构造方法定义
  • 当使用构造方法定义列表时,参数只能是可迭代的对象,构造方法会将参数中的元素构造成为列表的元素。 可以理解为将可迭代的对象强制类型转换为列表。
l1 = list("abc")
l2 = list((1,2,3))
l3 = list(((1,2,3),(4,5)))
l4 = list([1,2,3])
l5 = list([[1,2,3],[6,7]])
l6 = list(([1,2,3],[8,9]))
print(l1)
print(l2)
print(l3)
print(l4)
print(l5)
print(l6)
********************************
['a', 'b', 'c']
[1, 2, 3]
[(1, 2, 3), (4, 5)]
[1, 2, 3]
[[1, 2, 3], [6, 7]]
[[1, 2, 3], [8, 9]]
c、列表推导式方式定义

B、 列表中元素的引用

  • 使用下标形式引用列表中的元素。并且,下标不能超过列表的元素个数减1,否则会抛出下标越界错误。
l = [1,2,3,4,5]
print(l[0])# 1
print(l[3])# 4
print(l[5])# IndexError: list index out of range

C、列表的切片操作

  • 列表的切片操作同字符串一致,[start,end,tep];
l = [1,2,3,4,5]
print(l[0:3])
print(l[:3])
print(l[3:])
print(l[:])
# 逆序
print(l[::-1])
********************
[1, 2, 3]
[1, 2, 3]
[4, 5]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

D、列表的用途

  • 存储一组相关的数据:列表是一种有序的数据结构,可以用于存储一组相关的数据,如学生的成绩、员工的信息、商品的价格等。通过将相关的数据放入列表中,可以方便地进行统一的管理和处理。
  • 数据的容器:列表提供了便捷的操作方法,可以进行遍历、搜索、插入和删除等操作。通过索引,可以访问列表中的特定元素;通过遍历,可以逐个处理列表中的元素;通过方法,可以在列表中插入新元素、删除指定元素等。
  • 算法和数据结构中的应用:列表是一种重要的数据结构,广泛应用于算法和数据结构的实现中。例如,列表可以用于实现栈(Stack)、队列(Queue)、链表(LinkedList)等数据结构,还可以用于排序算法、搜索算法等的实现。

E、列表的增删改查操作

a、获取列表元素个数:len(list)
b、增加元素
  • append(value) 向列表最后追加元素;
  • extend(iterable) 将一个可迭代对象的元素依次添加到列表最后
l1 = [1,2,3]
l2 = ["a","b","c"]
l1.append(l2)# [1, 2, 3, ['a', 'b', 'c']] --整体添加到最后
print(l1) 
l1.extend(l2)# [1, 2, 3, ['a', 'b', 'c'], 'a', 'b', 'c'] --列表:依次添加到最后
print(l1)
l1.extend("456")# [1, 2, 3, ['a', 'b', 'c'], 'a', 'b', 'c', '4', '5', '6'] --字符串:依次添加到最后
print(l1)
l1.extend(("A","B","C"))# [1, 2, 3, ['a', 'b', 'c'], 'a', 'b', 'c', '4', '5', '6', 'A', 'B', 'C']  --元组:依次添加到最后
print(l1)
  • insert(index, value) 向列表指定下标位置插入一个元素,原有元素依次后移,如果指定下标超过元素个数,则插入到列表最后。
l = [1,2,3,4,5]
l.insert(0, "A")# ['A', 1, 2, 3, 4, 5]
print(l)
l.insert(3, "B")# ['A', 1, 2, 'B', 3, 4, 5]
print(l)
l.insert(10, "C")# ['A', 1, 2, 'B', 3, 4, 5, 'C'] --超过个数,放最后
print(l)
l.insert(9, "D")# ['A', 1, 2, 'B', 3, 4, 5, 'C', 'D']--超过个数,放最后
print(l)
c、删除元素
  • del 可以使用 del 关键字结合索引来删除指定位置的元素。如果指定的下标不存在则抛出一个错误。
l = [1,2,3,4,5,1,2,3]
del l[0] # [2, 3, 4, 5, 1, 2, 3]
print(l)
del l[10] # IndexError: list assignment index out of range
  • remove(value) 在列表中删除一个指定数据,如果删除的数据不存在则抛出错误;
l = [1,2,3,4,5,1,2,3]
l.remove(3) # [1, 2, 4, 5, 1, 2, 3]
print(l)
l.remove(33) # ValueError: list.remove(x): x not in list
  • pop(index) 从列表中取出并删除指定下标位置的元素,默认取出并删除最后一个元素,如果指定下标不存在,则会抛出一个错误。
l = [1,2,3,4,5,1,2,3,0]
print(l.pop())# 0
print(l)# [1, 2, 3, 4, 5, 1, 2, 3]
print(l.pop(3))# 4
print(l)# [1, 2, 3, 5, 1, 2, 3]
print(l.pop(10))# IndexError: pop index out of range
  • clear() 清空列表;
l = [1,2,3,4,5,1,2,3]
l.clear()
print(l)# []
print(len(l))# 0
d、修改元素
  • 通过下标的方式,对列表中的元素进行修改。
l = [1,2,3,4,5]
l[0] = 111
l[3] = 444
print(l) # [111, 2, 3, 444, 5]
e、查找操作
  • count(value) 在列表中统计参数 value 出现的次数
l = [1,2,3,4,5,1,2,3,3]
print(l.count(3)) # 3
  • index(value, start, stop) 在列表中查找参数 value 第一次出现的下标位置,如果给定范围则只在范围内查找,如果查找目标不存在则抛出错误。
l = [1,2,3,4,5,1,2,3,3]
print(l.index(3)) # 2
print(l.index(3,5,10)) # 7
print(l.index(0)) # ValueError: 0 is not in list
f、 列表排序
  • sort(key, reverse) 对列表进行排序

    • sort方法默认对基本数据类型进行升序排序;
    • reverse参数将列表元素排序后将列表逆序,实现降序排序;
    • key 参数用来指定排序规则,比如使用学生的年龄进行排序;–(TODO)
l = ["a","abc","ab","A"]
l.sort() # ['A', 'a', 'ab', 'abc'] --默认升序
print(l)
l = ["a","abc","ab","A"]
l.sort(reverse=True) # ['abc', 'ab', 'a', 'A'] --reverse=True降序
print(l)

(4)列表和元组的区别

  • 相同点
    • 元组和列表在Python中,都是有序的,可迭代的数据结构。
    • 元组和列表都是异构的,都可以存放不同数据类型的元素。
  • 不同点
    • 元组不可变的,不可以进行增删改操作,一旦定义,无法修改
    • 列表可变的,可以对列表中的元素进行增删改操作,空列表有实际意义
  • 内存占用
    • 由于元组与列表内部的实现机制不同,在相同元素和个数的情况下,元组占用内存空间更小
from sys import getsizeof
t = (1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(getsizeof(t))# 120 --元组
print(getsizeof(l))# 136 --列表

(5)字典

  • 特点:无序可变异构key唯一

A、字典的定义

  • Python 中使用花括号,保存key-value形式表示字典。
扩展:
  • key-value 中的 key 必须是一个可哈希的对象,可以使用 hash() 函数来判断数据是否可哈希;
    • 简单理解在一次程序运行结束前,无论该数据什么时候执行hash()函数,都能得到一个唯一确定的值。 一般情况下,不可变对象数据,都可以得到一个哈希值。 所以,理论上,pyhton中的不可变对象数据都可以做为key使用。 但是,为了方便使用,大多数情况下,都会使用字符串类型 数据做为key使用;
# 在一次程序运行过程中,hash函数都会得到同一个哈希值
print(hash("ab"))
print(hash("ab"))
print(hash("ab"))

def myhash():
    print(hash("ab"))

myhash()
**************************************
-1210825333212231616
-1210825333212231616
-1210825333212231616
-1210825333212231616
# 可哈希数据--不可变数据
print("*"*10)
print(hash(123))# 123
print(hash("abc"))# 15595928763702144
print(hash((1,2,3)))# 529344067295497451

# 不可哈希数据---可变数据
print(hash([1,2,3]))# TypeError: unhashable type: 'list'
print(hash((1,2,[3])))# TypeError: unhashable type: 'list'

B、字典的创建

a、字面量定义
d1 = {}
d2 = {"name": "Alice", "age": 25, "gender": "female"}

b、 构造方法定义字典
d1 = dict(one=1, two=2, three=3) # {'one': 1, 'two': 2, 'three': 3}---给键赋值
d2 = dict([('two', 2), ('one', 1), ('three', 3)]) # {'two': 2, 'one': 1, 'three': 3}--键值对组成元组-列表数据
d3 = dict((('two', 2), ('one', 1), ('three', 3))) # {'two': 2, 'one': 1, 'three': 3}---键值对组成元组-元组数据
d4 = dict([('two', 2), ['one', 1], ('three', 3)]) # {'two': 2, 'one': 1, 'three': 3}---键值对组成列表-列表数据
d5 = dict((('two', 2), ['one', 1], ('three', 3))) # {'two': 2, 'one': 1, 'three': 3}---键值对组成元组-元组数据
d6 = dict({'one': 1, 'two': 2, 'three': 3}) # {'one': 1, 'two': 2, 'three': 3}---花括号键值对
d7 = dict({'one': 1, 'three': 3}, two=2) # {'one': 1, 'three': 3, 'two': 2}--多种形式复合使用
d8 = dict(zip(['one', 'two', 'three'], [1, 2, 3])) # {'one': 1, 'two': 2, 'three': 3}---key列表和value列表
print(d1)
print(d2)
print(d3)
print(d4)
print(d5)
print(d6)
print(d7)
print(d8)
c、推导式定义

C、字典数据访问

  • 字典使用 key 来获取对应的值;—如果key不存在会报错;
  • 使用get(key)来获取对应的值;—如果key不存在会给个默认值,不会报错;
stu = {"name":"Tom", "age": 23, "gender":"male"}
print(stu["name"])# Tom
print(stu["age"])# 23
k = "gender"
print(stu[k]) # male

D、字典元素添加与修改

  • 字典中的每一个元素都以键值对形式表示,一个key对应一个value, 在一个字典中,key具有唯一性
    • 当给一个key赋值时,如果key在当前字典中不存在,则是添加数据;如果key存在,则对当前key所对应的值进行修改更新
stu = {"name":"Tom", "age": 23, "gender":"male"}
print(stu)
# 添加新元素
stu["address"] = "BeiJing"
print(stu)
# 修改数据
stu["name"] = "Jack"
stu["address"] = "ShangHai"
print(stu)

E、 字典元素的删除

  • 使用 del 通过key删除元素,当删除元素时,整个键值对都会被删除。
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
print(stu)
# 删除元素
del stu['age']
print(stu)
del stu['address']
print(stu)

F、 字典的有序性(Python 3.7+)

  • 在Python 3.7及更高版本中,字典被认为是有序的,即它们可以保持键值对的添加顺序。这意味着当遍历字典或打印字典时,键值对的顺序与它们添加到字典中的顺序相同。这种有序性是字典的内置特性,不需要额外的操作。

  • 然而,在Python 3.6及更早版本中,字典是无序的,无法保持键值对的顺序。这意味着当遍历字典或打印字典时,键值对的顺序是不确定的,可能与它们添加到字典中的顺序不同。

  • 因此,如果在编程中需要依赖字典键值对的顺序,建议使用Python 3.7及更高版本以确保有序性。如果使用旧版本的Python,可以考虑使用collections.OrderedDict来实现有序字典的功能。

G、 字典的应用场景

  • 字典适用于存储具有相关性的数据,如用户信息、学生成绩等。每个键值对表示一个独立的数据项,通过键来关联对应的值。

  • 字典提供了快速查找和访问数据的能力,通过键可以直接定位对应的值,而不需要遍历整个字典。这使得字典在需要根据特定键快速获取对应值的场景下非常有用。

  • 字典作为数据的容器,提供了丰富的操作方法,可以方便地进行遍历、搜索、插入和删除操作。可以通过循环遍历字典的键或值,通过键进行搜索和更新数据,通过键值对的添加和删除来动态修改字典的内容。这种灵活性使得字典成为处理各种数据结构的重要工具。

H、字典操作

a、 字典数据获取类操作
  • 获取所有键 keys() 用来获取字典中所有的 key, 保存到一个列表中,并以 dict_keys 类型返回;
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
ks = stu.keys()
print(ks)# dict_keys(['name', 'age', 'gender', 'address'])
print(type(ks))# <class 'dict_keys'>

for k in ks:
    print(stu[k])
"""
Tom
23
male
BeiJing
"""

  • 获取所有值values() 用来获取字典中所有的value, 保存到一个列表中,并以 dict_values 类型返回;
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
vs = stu.values()
print(vs)# dict_values(['Tom', 23, 'male', 'BeiJing'])
print(type (vs))# <class 'dict_values'>

for v in vs:
    print(v)
"""
Tom
23
male
BeiJing
"""
  • 获取所有条目items() 用来获取字典中所有的键值对,每一个元素键值对都以一个元组保存,将所有元素元组保存到一个列表中,并以 dict_items 类型返回;
print("*"*10)
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
ks = stu.items()
print(ks)# dict_items([('name', 'Tom'), ('age', 23), ('gender', 'male'), ('address', 'BeiJing')])

for k in ks:
    print(k)
"""
('name', 'Tom')
('age', 23)
('gender', 'male')
('address', 'BeiJing')
"""
for k in ks:
    print(k[0])
"""
name
age
gender
address
"""
  • 通过键获取值 get(key, default) 用来获取key对应的值,如果指定的key不存在,则返回默认值
    • 字典可以使用 字典对象[key] 的形式获取值,但是该方法如果指定的 key 不存在,程序会抛出一个错误。此时可以使用get() 替代该取值方法;
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
print(stu.get("name"))# Tom
print(stu.get("hobby"))# None
print(stu.get("hobby","无数据"))# 无数据
print(stu["hobby"])# KeyError: 'hobby'
b、 字典添加更新类操作
  • setdefault(key,default) 给一个不存在的key添加一个默认值并将该键值对保存到字典中。
    • 在一些场景下,字典的key存在,但是该key却没有对应的值,此时,就可以使用该方法,为当前的key添加一个默认值。比如服务端要保存客户端发起请求时携带的请求头中的信息。
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
stu.setdefault("hobby1")# {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing', 'hobby1': None}
print(stu)
stu.setdefault("hobby2", "无")# {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing', 'hobby1': None, 'hobby2': '无'}
print(stu)
stu.setdefault("name","newname")# {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing', 'hobby1': None, 'hobby2': '无'}
print(stu)
  • fromkeys(keys,val) 用于创建一个新字典,以序列 keys 中元素做字典的键,value 为字典所有键对应的初始值,默认为None
    • 该方法是一个静态方法,需要使用字典类型名 dict 调用。 该方法如果给定 keys 参数,则所有的key对应都为默认None ,如果给定 val值,则所有key对应的值为 val
ks = ("name", "age", "gender")
s1 = dict.fromkeys(ks)# {'name': None, 'age': None, 'gender': None} --值的默认是None
print(s1)
s2 = dict.fromkeys(ks,"无")# {'name': '无', 'age': '无', 'gender': '无'} --每个的值都是val
print(s2)
s3 = dict.fromkeys(ks,('tome','18','mela'))# {'name': ('tome', '18', 'mela'), 'age': ('tome', '18', 'mela'), 'gender': ('tome', '18', 'mela')} --每个的值都是val
print(s3)
  • update(d/iterable) 使用参数中的数据更新当前字典。
    • 该方法的参数可以接收一个字典(大多数的使用方式),也可以接收一个可迭代对象(列表、元组),如果参数数据中的key在当前字典中存在,则使用新值更新字典中的键值对,如果参数数据中的key在当前字内中不存在,则将键值对添加到当前字典中。
# 更新目标数据是一个字典
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
newStu = {"name":"Jack","hobby":"eat"}
stu.update(newStu)# {'name': 'Jack', 'age': 23, 'gender': 'male', 'address': 'BeiJing', 'hobby': 'eat'}
print(stu)
# 更新目标数据是一个可迭代对象
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
newStu = (("name","Rose"),["hobby","play"])
stu.update(newStu)
print(stu)
c、 字典删除类操作
  • 使用 del 通过key删除元素,当删除元素时,整个键值对都会被删除。
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
print(stu)
# 删除元素
del stu['age']
print(stu)
del stu['address']
print(stu)
  • popitem() 用来获取并删除字典中的最后一个键值对返回一个元组,如果字典为空时,则抛出一个错误;
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
v = stu.popitem()
print(v) # ('address', 'BeiJing')
print(stu)# {'name': 'Tom', 'age': 23, 'gender': 'male'}

v = stu.popitem()
print(v) # ('gender', 'male')
print(stu)# {'name': 'Tom', 'age': 23}

print({}.popitem())# KeyError: 'popitem(): dictionary is empty'
  • pop(key) 用于获取并删除字典中指定key对应的键值对。如果指定的key不存在,则抛出错误
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
v = stu.pop("name")# Tom
print(v) # Tom
print(stu) # {'age': 23, 'gender': 'male', 'address': 'BeiJing'}
v1 = stu.pop('hobby') # KeyError: 'hobby'
  • clear() 清空字典中所有的键值对元素;
stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
print(stu)
stu.clear()
print(stu) # {}

(6)集合

A、什么是集合

  • 集合是一种数据类型,用于存储多个元素,并确保元素的唯一性。
  • 集合中的元素是无序的,不可通过索引或切片进行访问。
  • 集合的主要特点是元素不重复,相同的元素在集合中只会出现一次。
  • 我们可以使用大括号 {} 或 set() 函数来定义和创建集合。
  • 集合提供了各种集合运算,如并集(两个集合中的所有元素)、交集(两个集合中共有的元素)、差集(第一个集合中存在而第二个集合中不存在的元素)等操作。

B、集合的创建

  • 不能使用 {} 创建一个空集合,因为此种方式创建的类型为字典。
    • 使用{val,val,val…}创建集合;
    • 使用set(iterable)创建集合;
    • 使用集合推导式创建集合;
# 不能使用花括号 {} 来定义一个空集合
s1 = set()
s2 = {}
print(type(s1)) # <class 'set'>
print(type(s2)) # <class 'dict'>

# 使用花括号 {},在内部添加元素,用逗号 , 分隔
my_set = {1, 2, 3, 4, '5'}
print(my_set) # {1, 2, 3, 4, '5'} --顺序为创建的顺序
print(type(my_set)) # <class 'set'>

my_set_04 = {"12345"}
print("my_set_04:",my_set_04) # my_set_04: {'12345'} --一个元素的集合

# 使用内置函数 set(iterable) 创建集合
my_set_01 = set([1, 2, 3, 4, 5])
print("my_set_01:",my_set_01) # my_set_01: {1, 2, 3, 4, 5} --顺序为创建的顺序
my_set_02 = set((1, 2, 3, 4, 5))
print("my_set_02:",my_set_02) # my_set_02: {1, 2, 3, 4, 5} --顺序为创建的顺序
my_set_03 = set("12345")
print("my_set_03:",my_set_03) # my_set_03: {'2', '4', '3', '5', '1'} --顺序随机

# 集合元素具有唯一性
s = {1,1,1,2,3,4,5,6,6,6,6,6,6,6}
print(s) # {1, 2, 3, 4, 5, 6}

C、集合的使用场景

  • 集合常见的用途包括成员检测、从序列中去除重复项以及数学中的集合类计算,例如交集、并集、差集与对称差集等等。

  • 由于集合不支持下标操作,所以不支持常规方式的获取和修改。

D、集合操作

a、添加操作
  • add(ele) 向集合最后添加一个元素,如果元素已存在则原集合保持不变;
s = {1, 2, 3}
s.add(4)
s.add(5)
print(s)# {1, 2, 3, 4, 5}
s.add("Hello")
s.add("Hello")
print(s)# {1, 2, 3, 4, 5, 'Hello'}
  • update(interable) 更新集合,在最后添加来自 interable中的所有元素,interable是一个可迭代对象,如果数据在集合中存在则不更新。注意:集合是无序的,添加元素的顺序貌似有点规律,但是这个规律不重要;
s = {1, 2, 3}
s.update((4,5,6))
print(s)# {1, 2, 3, 4, 5, 6} --元组
s.update([5,6,7])
print(s)# {1, 2, 3, 4, 5, 6, 7} --列表
s.update({6,7,8,9,10,11,'A'})
print(s)# {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'A'} --集合
s.update("abc")
print(s)# {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 'b', 'a', 'A', 'c'} --字符串
b、删除操作
  • pop() 从集合中移除并返回任意一个元素,如果集合为空,则抛出错误
s = {1, 2, 3,'a','A','abc'}

print(s.pop())
print(s)
print(s.pop())
print(s)
print(s.pop())
print(s)
print(s.pop())
print(s) # {'A', 'a'} --被随机删除了4个,而且这个结果每次会不一样
  • remove(elem) 从集合中移除指定元素 elem,返回None。 如果 elem 不存在于集合中则抛出错误。
s = {'a',1, 2, 3,'B'}

print(s.remove(1))# None
print(s)# {2, 3, 'B', 'a'}
print(s.remove('B'))# None
print(s)# {2, 3, 'a'}
print(s.remove(5))# KeyError: 5
  • discard(elem) 如果元素 elem 存在于集合中则将其移除返回None,如果elem不存在,则什么也不做;
s = {'a',1, 2, 3,'B'}
print(s.discard(2))# None
print(s)# {1, 3, 'a', 'B'}
print(s.discard('a'))# None
print(s)# {1, 3, 'B'}
print(s.discard('A'))# None
print(s)# {1, 3, 'B'}
  • clear() 清空集合;
s = {1, 2, 3}
print(s.clear())# None
print(s)# set() --之所以不是{},那是因为空{}表示字典

F、集合数据操作

a、 判断两个集合是否不相交
  • isdisjoint(other) 如果集合中没有与 other 共有的元素则返回 True。 当且仅当两个集合的交集为空集合时,两者为不相交集合。
s = {1, 2, 3}
print(s.isdisjoint({4, 5, 6}))# True
print(s.isdisjoint({3, 4, 5}))# False
b、 判断集合是否是另一个集合的子集
  • issubset(other) 检测是否集合中的每个元素都在 other 之中。
    • 也可以通过运算符 <=直接判断子集
    • < 判断是否为真子集
s = {1, 2, 3}

# 判断 s 是否为 other参数的子集
print(s.issubset({1, 2, 3}))# True
print(s.issubset({1, 2, 3, 4}))# True
print(s.issubset({3, 4, 5}))# False
print("*" * 10)
# 也可以通过运算符 <= 直接判断
print(s <= {1, 2, 3})# True
print(s <= {1, 2, 3, 4})# True
print(s <= {3, 4, 5})# False
print("*" * 10)

# 判断是否为真子集
print(s < {1, 2, 3})# False -------
print(s < {1, 2, 3, 4})# True  -------包含不等
print(s < {3, 4, 5})# False
c、 判断集合是否是另一个集合的超集
  • issuperset(other) 检测是否 other 中的每个元素都在集合之中。–A完全包含B,那A就是B的超集,不相等就是真超集;–一个是子集那另一个就是它的超集;
    • 也可以通过运算符 >= 直接判断超集
    • >判断是否为真超集
print("-"*10)
s = {1, 2, 3, 4}

# 判断 s 是否为 other参数的超集
print(s.issuperset({1, 2, 3}))# True
print(s.issuperset({1, 2, 3, 4}))# True
print(s.issuperset({3, 4, 5}))# False
print("*" * 10)
# 也可以通过运算符 >= 直接判断
print(s >= {1, 2, 3})# True
print(s >= {1, 2, 3, 4})# True
print(s >= {3, 4, 5})# False
print("*" * 10)

# 判断是否为真超集
print(s > {1, 2, 3})#  True
print(s > {1, 2, 3, 4})# False --包含不等
print(s > {3, 4, 5})# False
d、 并集
  • union(*other) 返回一个新集合,其中包含来自原集合以及 others 指定的所有集合中的元素,other可以指定多个集合。
    • 也可以使用 | 进行集合并集运算;
print("-"*10)
s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}
s3 = {5, 6, 7, 8}
print(s1.union(s2))# {1, 2, 3, 4, 5, 6}
print(s1.union(s2,s3))# {1, 2, 3, 4, 5, 6, 7, 8}
# 也可以使用 | 进行集合并集运算
print(s1 | s2)# {1, 2, 3, 4, 5, 6}
print(s1 | s2 | s3)# {1, 2, 3, 4, 5, 6, 7, 8}
e、交集
  • intersection(*others) 返回一个新集合,其中包含原集合以及 others 指定的所有集合中共有的元素。
    • 也可以使用 & 进行集合交集运算;
print("-"*10)
s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}
s3 = {5, 6, 7, 8}
print(s1.intersection(s2))# {3, 4}
print(s1.intersection(s2, s3))# set()
print(s1.intersection(s3))# set()
print("*" * 10)
# 也可以使用 & 进行集合交集运算
print(s1 & s2)# {3, 4}
print(s1 & s2 & s3)# set()
print(s1 & s3)# set()

f、 差集
  • difference(*others) 返回一个新集合,包含原集合中在 others 指定的其他集合中不存在的元素。
    • 也可以使用 - 进行集合差集运算;–在原集合中干掉并集部分;
print("-"*10)
s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}
s3 = {5, 6, 7, 8}
print(s1.difference(s2))# {1, 2}
print(s1.difference(s2, s3))# {1, 2}
print(s1.difference(s3))# {1, 2, 3, 4}
print("*" * 10)
# 也可以使用 - 进行集合差集运算
print(s1 - s2)# {1, 2}
print(s1 - s2 - s3)# {1, 2}
print(s1 - s3)# {1, 2, 3, 4}
g、对称差集
  • symmetric_difference(other) 返回一个新集合,其中的元素或属于原集合或属于 other 指定的其他集合但不能同时属于两者。–干掉相交之后的并集;
    • 也可以使用 ^ 进行集合对称差集运算;
print("-"*10)
s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}
s3 = {5, 6, 7, 8}
print(s1.symmetric_difference(s2))# {1, 2, 5, 6}
print(s1.symmetric_difference(s3))# {1, 2, 3, 4, 5, 6, 7, 8}
print("*" * 10)
# 也可以使用 ^ 进行集合对称差集运算
print(s1 ^ s2)# {1, 2, 5, 6}
print(s1 ^ s3)# {1, 2, 3, 4, 5, 6, 7, 8}

(7)推导式

A、什么是推导式

  • Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。

  • Python 支持各种数据结构的推导式:

    • 元组(tuple)推导式
    • 列表(list)推导式
    • 字典(dict)推导式
    • 集合(set)推导式

B、 元组推导式

  • 元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。

  • 元组推导式基本格式为圆括号包裹:(out_exp_res for item in Sequence )(out_exp_res for item in Sequence if conditional )

    • out_exp_res:生成元素表达式,可以是有返回值的函数。
    • for out_exp in Sequence:迭代 Sequence 将 out_exp 传入到 out_exp_res 表达式中。
    • if condition:条件语句,可以过滤Sequence中不符合条件的值。
# 简单的元组推导式
t1 = (x for x in range(1,10))
print(t1)# <generator object <genexpr> at 0x0000022A3A749630>
print(type(t1))# <class 'generator'>
print(tuple(t1))# (1, 2, 3, 4, 5, 6, 7, 8, 9)
# 生成128位ASCII码元组
t2 = (chr(x) for x in range(128))
print(t2)# <generator object <genexpr> at 0x0000028595608C80>
# 生成100以内能被7整除所有数字的元组
t3 = (x for x in range(100) if x%7==0)
print(t3)# <generator object <genexpr> at 0x000002859551FED0>
# 生成99乘法表结果元组
t4 = (x*y for x in range(1,10) for y in range(1, x+1))
print(t4)# <generator object <genexpr> at 0x0000028595581120>
words = ["apple", "banana", "cherry"]
upper_words = (word.upper() for word in words)
print(upper_words)# <generator object <genexpr> at 0x00000285955F8040>

for t in t1:
    print(t,end=" ") # 1 2 3 4 5 6 7 8 9
    
  • 注意:元组推导式得到的结果为生成器generator类型,并不是元组类型,但是可以通过遍历获取,不能通过角标获取;可以通过强制类型转换tuple(generator)转成元组

C、拓展- python 迭代器 iterator 生成器 generator

Python3 迭代器与生成器

D、列表推导式

  • 列表 可以利用 range 区间、元组、列表、字典和集合等数据类型 ,快速生成一个满足指定需求的列表;
  • 列表推导式格式为中括号包裹:[out_exp_res for item in Sequence ][out_exp_res for item in Sequence if conditional ]
    • out_exp_res:生成元素表达式,可以是有返回值的函数。
    • for out_exp in Sequence:迭代 Sequence 将 out_exp 传入到 out_exp_res 表达式中。
    • if condition:条件语句,可以过滤Sequence中不符合条件的值。
  • 结果为列表数据类型;
# 简单的元组推导式
l1 = [x for x in range(1,10)]
print(l1)# [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(type(l1))# <class 'list'>
# 生成128位ASCII码元组
l2 = [chr(x) for x in range(128)]
print(type(l2))# <class 'list'>
# 生成100以内能被7整除所有数字的元组
l3 = [x for x in range(100) if x%7==0]
print(l3) # [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]
# 生成99乘法表结果元组
l4 = [x*y for x in range(1,10) for y in range(1, x+1)]
print(l4)
# 将列表中的字符串转换为大写
words = ["apple", "banana", "cherry"]
upper_words = [word.upper() for word in words]
print(upper_words)# ['APPLE', 'BANANA', 'CHERRY']

E、字典推导式

  • 字典推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的字典;
  • 结果表达式需要使用 key:value 形式;
  • 推导式格式为花括号包裹;{ key_expr: value_expr for value in collection }或{ key_expr: value_expr for value in collection if condition }
  • 结果为字典类型
names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
# 将列表中各字符串值为键,各字符串的长度为值,组成键值对
newdict = {name:len(name) for name in names}
print(newdict)# {'Bob': 3, 'Tom': 3, 'alice': 5, 'Jerry': 5, 'Wendy': 5, 'Smith': 5}
print(type(newdict))# <class 'dict'>

F、集合推导式

  • 集合推导式与字典推导式的区别在于结果表达式是单一结果,不是key-value形式
  • 推导式格式为花括号包裹,单一结果: { expression for item in Sequence }{ expression for item in Sequence if conditional }
data = ['Bob','123','Tom','ab123','alice','123abc','Jerry','456','Wendy','554','Smith']
# 筛选列表中的数字字符串
newset = {n for n in data if n.isdigit()}
print(newset)# {'456', '554', '123'}
print(type(newset))# <class 'set'>

G 、推导式的优点

  • 简洁高效:推导式允许在一行代码中完成复杂的生成操作,避免了使用显式的循环和临时变量的繁琐过程。这样可以大大减少代码量,并提高编码效率。

  • 可读性好:推导式使用简洁的语法,将迭代、条件判断和表达式结合在一起,使得代码更加紧凑和易于理解。它提供了一种清晰、直观的方式来表达列表生成的逻辑,使得代码更加可读性强,降低了出错的可能性。

  • 灵活性强:推导式非常灵活,可以根据需要添加条件判断、多个迭代变量和嵌套结构,以满足不同的需求。这使得推导式适用于各种场景,从简单的数据转换到复杂的筛选和操作,都可以通过简单而直观的语法实现。

  • 总的来说,推导式提供了一种简洁高效、可读性好和灵活性强的方法来处理列表数据。它是Python中强大而常用的特性之一,为开发者提供了更好的编码体验和效率。