python学习笔记——复合数据(列表 元组 字符串 字典 集合)
Python的数据结构——列表 元组 字典 集合 字符串
列表
- 列表是可变的
列表的定义(如何创建一个列表)
方法一:直接创建,要求里面的内容都是知道的,并且是可列出来的
l=['C','C++','Java']#直接定义列表 里面可以填变量
方法二:使用range 创建数字列表
num=list(range(1,5)
其实这里之只需要一个迭代器即可) #通过range定义数字列表 左闭右开
方法三:使用eval讲字符串形式的列表转化成列表
使用eval构建列表(通常用在输入的列表被当作字符串的时候,因为列表没办法直接输入,输入的只能是字符串,这时候就要用eval)
eval函数:相当于执行字符串中的表达式
x=eval(input())
但是当输入的是数字类型的,最好别使用eval,还是老老实实用 int() float()等等
方法四:列表解析
list=[val for i in 可迭代元素 if condition]
- for i in 可迭代元素 if condition 可以灵活嵌套 整体按照从左往右运行
["Even" if i % 2 == 0 else "Odd" for i in range(6)]
#这里的用到了条件三元表达式 "Even" if i % 2 == 0 else "Odd"这一部分本质上是一个表达式
[print(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]#这句话
会产生无意义的列表
print() 函数返回 None,所以这个推导式会生成一个全是 None 的列表:
[None, None, None, None, None, None, None]
这个列表完全没用,只是浪费了内存。
- 列表推导式的本意是生成新列表,而不是用来执行 print 这类 “副作用” 操作。+
- 别人读代码时会误以为你要生成一个列表,而不是单纯打印。
使用列表解析实现矩阵转置
matrix = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]d
[[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
列表的输出
print(l[0],l[1],'\n',l[2],'\n')
print(num[-1])
print(list)#也可以直接输出列表
修改列表元素
- 列表里面互相的赋值操作都不是复制,而是指向同一个东西
l[0]='Prt'#直接修改
l.append('Go')//作为单个元素,添加到列表的末尾
x.extend(一个可迭代元素,就是能用for访问每一位的元素,比如说字符串 列表元组range对象,集合set)
l.insert(1,'插入insert')//在下标为1的位置插入'插入insert'
l.pop()#弹出最后一个元素
l.pop(1)#删除坐标为1的元素
del l[0]# 等效于上一句
l.remove('Go')#在l中删除'Go'
列表的比较
x == y
x is y
列表自带功能函数
排序
x=[3,4,5,6,7,8,9,0]
x.sort()
参与运算
x in list#判断一个元素是否在list里面
list1+list2#两个列表相加
list*3
max(list)#取最大值
sum(list)#求和
遍历列表元素
声明式操作
y=[1,2,3,4]
for x in y:
……C操作
玛卡巴卡
命令式操作
for i in range(0,4)
……操作
知识点:列表切片
list=[1.2.3.4.5]
A=list[start:end:step]#范围内没有元素则返回空列表
知识点:列表的复制
浅层复制
a1=[1,2,3,4,5]
b=a1.copy()////注意这里b is a1是假的 但是他们指向的元素地址是相同的
深层复制
from copy import deepcopy
c=deepcopy(a1)//所有指向的元素也换成新的
字符串 字符串不可变
字符串的访问
s="lmy"
print(s)#直接访问
print(s[0])#下标访问
print(s[1:])#切片访问返回字符串
字符串能进行的操作
- 能进行加法乘法
- len(str) 返回长度
- sorted(str)返回了一个字符列表(!!!注意)
- reserved(str)返回一个迭代器对象,直接打印只能显示对象的内存地址,需要通过转换转标为其他类型,比如可以通过list()转化成字符列表
print(sorted(s))
print(reversed(s))#会有乱码
print(s.upper())#全部变成大写
print(s.lower())#全部变成小写
s.split()
//不传入参数时,以任意空白字符(空格、制表符\t、换行符\n等)作为分隔符
//结果返回一个字符列表
s.lstrip()
s.rstrip()
isspace()函数
s1 = " "
print(s1.isspace()) # 输出:True
检查字符串是否只包含空白字符(空格、换行 \n、制表符 \t、回车 \r 等),且字符串非空。
返回值:布尔类型(True / False)
- index
列表.index(查找的元素, 起始索引, 结束索引)
#index() 找不到元素会报错,建议先用 in 判断元素是否存在:
if "Go" in l:
print(l.index("Go"))
else:
print("元素不存在") # 输出:元素不存在
字符串的find()与index() 功能类似,但找不到元素时返回-1而非报错:
#字符串的 find() 是更安全的替代(找不到返回 - 1),列表 / 元组无 find() 方法,只能用 index()!!!!!
关于split()
s.split(' ') 仅按单个空格分割,连续空格会产生空串 "a b".split(' ') → ['a', '', 'b']
字符串和format函数的配合使用
1.类似print(f" {表达式}")的功能
基础位置匹配
s1 = "我学{}和{}".format("Python", "Java")
print(s1) # 输出:我学Python和Java
指定位置索引(可重复使用、调整顺序)
s2 = "我学{1}和{0}".format("Python", "Java")
print(s2) # 输出:我学Java和Python
用关键字参数匹配占位符
s3 = "姓名:{name},年龄:{age}".format(name="张三", age=20)
print(s3) # 输出:姓名:张三,年龄:20
结合字典(用**解包)
info = {"name": "李四", "age": 25}#这是一个字典
s4 = "姓名:{name},年龄:{age}".format(**info)
print(s4) # 输出:姓名:李四,年龄:25
2.一些数字操作
保留小数(保留2位)
{:.2f}保留两位小数
num1 = 3.1415926
s5 = "圆周率:{:.2f}".format(num1)
print("{:.2f}".format(num1))
print(s5) # 输出:圆周率:3.14
整数补零(总长度5,不足补0)
{:05d}整数高位补零
num2 = 123
s6 = "编号:{:05d}".format(num2)
print(s6) # 输出:编号:00123
百分比格式(保留1位小数)
{:.1%}保留一位小数 的百分比形式
rate = 0.85
s7 = "通过率:{:.1%}".format(rate)
print(s7) # 输出:通过率:85.0%
列表取值(索引)
lang = ["Python", "Java", "C++"]
s8 = "首选语言:{0[0]},次选:{0[1]}".format(lang)
print(s8) # 输出:首选语言:Python,次选:Java
字典取值(键)
person = {"name": "王五", "score": 98.5}
s9 = "{p[name]}的分数:{p[score]}".format(p=person)#不知道为啥但是这里确实只能使用p=
print(s9) # 输出:王五的分数:98.5
:d 整数格式 "{:d}".format(123) 123
:f 浮点数格式 "{:.2f}".format(3.1415) 3.14
:% 百分比格式 "{:.1%}".format(0.8) 80.0%
:0nd 整数补零(n 为总长度) "{:05d}".format(12) 00012
:, 千分位分隔符 "{:,}".format(1000000) 1,000,000
- count
# 定义字符串
s = "hello world, hello python"
# 统计单个字符的次数
print(s.count("l")) # 输出:3(字符l出现3次)
# 统计子字符串的次数
print(s.count("hello")) # 输出:2(子串hello出现2次)
#字符串 "aaaaaa" 中,"aa" 会出现在位置 0-1、2-3、4-5,共 3 次(count() 不会统计重叠的子串)。
# 忽略大小写统计(先统一转小写)
print(s.lower().count("HELLO".lower())) # 输出:2(大小写不敏感统计)
- encode
# 定义包含中文的字符串
s = "Python 编程"
# 默认 UTF-8 编码(最常用)
b = s.encode()
print("编码后(字节类型):", b)
print("类型:", type(b)) # 输出:<class 'bytes'>
# 解码(反向操作,字节转字符串)
s2 = b.decode("utf-8")
print("解码后:", s2) # 输出:Python 编程
- join
join() 是字符串的内置方法,作用是:将一个包含字符串的可迭代对象(列表、元组、字符串等),通过指定的「分隔符字符串」拼接成一个新字符串。
分隔符字符串.join(可迭代对象)
「分隔符字符串」:可以是空字符串、空格、逗号、竖线等任意字符串;
「可迭代对象」:必须是所有元素都是字符串的序列(列表、元组、字符串等),否则会报 TypeError。
示例 1:列表拼接(最常用)
# 用空字符串拼接(无分隔符)
lang_list = ["Python", "Java", "C++"]
s1 = "".join(lang_list)
print(s1) # 输出:PythonJavaC++
# 用逗号+空格拼接
s2 = ", ".join(lang_list)
print(s2) # 输出:Python, Java, C++
# 用换行符拼接
s3 = "\n".join(lang_list)
print(s3)
# 输出:
# Python
# Java
# C++
示例 2:元组 / 字符串拼接
# 元组拼接(用法和列表一致)
num_tuple = ("1", "2", "3")
s4 = "-".join(num_tuple)
print(s4) # 输出:1-2-3
# 字符串拼接(按字符拆分后再拼接)
s5 = "abc"
s6 = "|".join(s5)
print(s6) # 输出:a|b|c
错误示例(包含整数,直接拼接报错)
num_list = [1, 2, 3]
s_error = ",".join(num_list) # 报错:TypeError: sequence item 0: expected str instance, int found
正确写法(**先转字符串**)
num_list = [1, 2, 3]
# 用列表推导式把每个元素转字符串
s7 = ",".join(str(num) for num in num_list)
print(s7) # 输出:1,2,3
- replace
replace() 是字符串的内置方法,作用是:将字符串中的指定子串替换为新的子串,返回一个替换后的新字符串(原字符串不会被修改,因为 Python 字符串是不可变类型)
字符串.replace(旧子串, 新子串, 替换次数)
旧子串:必填,要被替换的字符 / 子串;
新子串:必填,用来替换的字符 / 子串;
替换次数:可选,指定最多替换多少次(默认 -1,表示替换所有匹配项)。
示例 1:替换所有匹配项(默认)
# 定义原始字符串
s = "Python 是一门语言,Python 简单易学,我喜欢 Python"
# 替换所有 "Python" 为 "Java"
new_s = s.replace("Python", "Java")
print("原字符串:", s)
print("替换后:", new_s)
示例 2:指定替换次数
# 只替换前2个 "Python"
new_s2 = s.replace("Python", "Java", 2)
print(new_s2) # 输出:Java 是一门语言,Java 简单易学,我喜欢 Python
示例 4:替换为空字符串(删除子串)
# 移除所有逗号
s4 = "1,2,3,4,5"
new_s4 = s4.replace(",", "")
print(new_s4) # 输出:12345
元组
Python中元组的两大核心价值:保护数据不可变 + 高效的
多用于 packing / unpacking来实现数据传递
创建元组
1.使用小括号 () 直接创建
2.使用 tuple() 类型转换(通用)
可将可迭代对象(列表、字符串、range、字典等)转换为元组,适合从其他类型生成元组。
3.通过解包 + 打包创建新元组
结合之前讲的 packing/unpacking,快速拼接元组。
t1 = (1, 2)
t2 = (3, 4)
拼接两个元组生成新元组
new_tuple = t1 + t2
print(new_tuple) # 输出:(1, 2, 3, 4)
# 重复元组元素(生成新元组)
repeat_tuple = t1 * 3
注意
wrong_tuple = (10) # 这是整数,不是元组!
print(type(wrong_tuple)) # 输出:<class 'int'>
correct_tuple = (10,) # 正确,加逗号
packing&unpacking
元素数量可变的unpacking情形(星号操作符*)
>>> a, *b = 1, 2, 3
>>> a
1
>>> b
[2, 3]
Zip 和*
zip() 会将多个可迭代对象(列表、元组、字符串等)中对应位置的元素打包成元组,返回一个 zip 迭代器;若可迭代对象长度不一致,以最短的为准。
list1 = [1, 2, 3]
list2 = ["a", "b", "c"]
zipped = zip(list1, list2)
// 转换为列表查看结果(zip迭代器需转换才能可视化)
print(list(zipped)) # 输出:[(1, 'a'), (2, 'b'), (3, 'c')]
和*
- 称为解包运算符,核心作用是将可迭代对象(列表、元组、zip 迭代器等)的元素「打散」成独立参数 / 元素。


仅有三种mutable的容器可以用解析方法创建(list, set, dict)
字典
字典的键必须是不可变类型(字符串、数字、元组),列表、字典等可变类型不能作为键
创建字典
1. 直接用 {} 字面量创建(推荐)
这是最简单、最直观的方式,直接写 {键: 值, 键: 值...}。
# 空字典
empty_dict = {}
print(empty_dict) # 输出: {}
# 有初始键值对的字典
student = {
"name": "Lilin",
"salary": 4500,
"age": 25
}
print(student) # 输出: {'name': 'Lilin', 'salary': 4500, 'age': 25}
2.用 dict() 构造函数创建
适合从其他数据(如列表、元组)生成字典,或动态创建字典
# 方式1:关键字参数(键必须是合法的变量名,不能有空格/特殊字符)
person = dict(name="Mayue", salary=3000, city="Beijing")
print(person) # 输出: {'name': 'Mayue', 'salary': 3000, 'city': 'Beijing'}
# 方式2:可迭代对象(列表/元组包含键值对元组)
score = dict([("math", 90), ("english", 85), ("chinese", 95)])
print(score) # 输出: {'math': 90, 'english': 85, 'chinese': 95}
# 方式3:创建空字典
empty_dict2 = dict()
print(empty_dict2) # 输出: {}
3. 字典推导式(高效生成字典)
适合根据已有数据快速生成字典,语法和列表推导式类似。
# 示例1:从列表生成(键值一一对应)
names = ["Lilin", "Mayue", "Wuyun"]
salaries = [4500, 3000, 8000]
salary_dict = {name: salary for name, salary in zip(names, salaries)}
print(salary_dict) # 输出: {'Lilin': 4500, 'Mayue': 3000, 'Wuyun': 8000}
# 示例2:带条件过滤
filtered_dict = {name: salary for name, salary in salary_dict.items() if salary > 4000}
print(filtered_dict) # 输出: {'Lilin': 4500, 'Wuyun': 8000}
4.从 zip() 直接创建
适合两个可迭代对象(列表、元组等)分别作为键和值时。
keys = ["a", "b", "c"]
values = [1, 2, 3]
zip_dict = dict(zip(keys, values))
print(zip_dict) # 输出: {'a': 1, 'b': 2, 'c': 3}
5. fromkeys() 批量创建(值默认相同)
适合快速创建「键不同、值相同」的字典,比如初始化默认值。
# 方式1:默认值为 None
default_dict = dict.fromkeys(["apple", "banana", "orange"])
print(default_dict) # 输出: {'apple': None, 'banana': None, 'orange': None}
# 方式2:指定统一默认值
count_dict = dict.fromkeys(["apple", "banana", "orange"], 0)
print(count_dict) # 输出: {'apple': 0, 'banana': 0, 'orange': 0}
字典中元素的提取
###提取键为一个列表
>>> sd1 = {'Mayue': 3000, 'Lilin': 4500, 'Wuyun': 8000}
>>> sd1.keys()
###提取值为一个列表
dict_keys(['Mayue', 'Lilin', 'Wuyun'])
>>> sd1.values()
dict_values([3000, 4500, 8000])
###提取对应关系为一个元素为元组的列表
>>> sd1.items()
dict_items([('Mayue', 3000), ('Lilin', 4500), ('Wuyun', 8000)])
ord()和chr()函数
#####ord()和chr()函数
# ASCII 字符转换(数字、字母、符号)
print(ord('a')) # 输出:97(小写a的ASCII码)
print(ord('A')) # 输出:65(大写A的ASCII码)
print(ord('0')) # 输出:48(数字0的ASCII码)
print(ord(' ')) # 输出:32(空格的ASCII码)
print(ord('!')) # 输出:33(感叹号的ASCII码)
# 非ASCII字符(Unicode)也支持
print(ord('中')) # 输出:20013(中文“中”的Unicode编码)
# ASCII 编码转回字符
print(chr(97)) # 输出:a
print(chr(65)) # 输出:A
print(chr(48)) # 输出:0
print(chr(32)) # 输出:(空格)
print(chr(33)) # 输出:!
# Unicode 编码转回字符
print(chr(20013)) # 输出:中
print(chr(128512))# 输出:😂(emoji表情的Unicode编码)
按某顺序访问字典元素:
• 对keys()排序后依次访问对应的value
• 使用内建排序函数sorted():
• 得到一个(key, value)的list,按sorted函数调用时指定的顺序排列
>>> sd1 = {'Mayue': 3000, 'Lilin': 4500, 'Wuyun': 8000}
>>> sorted(sd1.items())
[('Lilin', 4500), ('Mayue', 3000), ('Wuyun', 8000)]
#sorted() 函数默认按照 Unicode 码点(ASCII 值) 进行排序
示例1:字符串键(按字母序排序)
fruit_price = {"apple": 5, "banana": 3, "orange": 4, "pear": 2}
#步骤1:提取并排序键
sorted_keys = sorted(fruit_price.keys())
print("排序后的键:", sorted_keys) # 输出:['apple', 'banana', 'orange', 'pear']
# 步骤2:遍历排序后的键,访问对应值
for key in sorted_keys:
print(f"{key}: {fruit_price[key]}")
# 输出:
# apple: 5
# banana: 3
# orange: 4
# pear: 2
示例2:数字键(按数字大小排序)
score = {3: 90, 1: 85, 4: 95, 2: 88}
for key in sorted(score.keys()):
print(f"第{key}名:{score[key]}分")
# 输出:
# 第1名:85分
# 第2名:88分
# 第3名:90分
# 第4名:95分


浙公网安备 33010602011771号