python的列表
- 一、序列
- 1. 序列定义
- 2. 序列数据类型包括
- 3.特点:都支持下面的特性
- 二、 列表
- 1. 列表的创建
- 2. 列表的基本特性
- (1) 连接操作符喝重复操作符
- (2) 成员操作符(in , not in )
- (3) 索引
- (4) 切片
- 练习
- (5) for循环
- 3. 列表的常用方法
- (1) 一次添加一个元素
- (2) 增加列表的内容
- (3) 修改列表内容:通过索引和切片重新赋值的方式
- (4) 查看:通过索引和切片查看元素
- (5) 删除列表中某元素
- 4. 列表的翻转,排序,拷贝功能
- 三、元组tuple的操作(戴了紧箍咒的列表,不能修改元素)
- 1. 元组的创建
- 2. 元组的特性
- 3. 常用方法
- 四、 命名元组的使用
- 练习
- 五、地址引用和深拷贝和潜拷贝
- 1. 数据类型分类
- 2. 值得引用
- 3. 潜拷贝
- 4. 深拷贝
- 如果列表的元素包含可变数据类型(可增删改:list) ,一定要用深拷贝!!!!
- 5. 浅拷贝与深拷贝的区别
- 6. 结论
一、序列
1. 序列定义
- 成员有序排列的,且可以通过下标偏移量访问到它的一个或者几个成员,这类类型统称为序列
2. 序列数据类型包括
- 字符串,列表,元组
3.特点:都支持下面的特性
- 索引和切片操作符
- 成员关系操作符(in,not in)
- 连接操作符(+)和重复操作符(*)
二、 列表
1. 列表的创建
li = []
print(li, type(li))
2. 列表的基本特性
(1) 连接操作符喝重复操作符
print([1,2] + [2,3]) #输出[1, 2, 2, 4]
print([1,2] * 3) #输出[1, 2, 1, 2, 1, 2]
(2) 成员操作符(in , not in )
print(1 in [1,2,3]) #输出True
print(1 in ["a", True, [1,2]]) #输出True. 原因:在布尔类型里面,True为1,False为0,此处将1=True
print("z" in ["a", True, [1,2,"z"]]) #输出False
split’,'[172,25,254,100]
(3) 索引
li = [1,2,3,[1,"b",3]]
print(li[0]) #输出1
print(li[-1]) #输出[1,"b",3]
print(li[-1][0]) #输出1
print(li[3][-1]) #输出3
(4) 切片
li =['172','25','254','100']
print(li[:3]) #['172', '25', '254']
print(li[1:]) #['25', '254', '100']
print(li[::-1]) #倒着输出['100', '254', '25', '172']
练习
# 需求:已知列表list =['172','25','254','100'],请输出“100-254-25”
print('-'.join(li[-3:0:-1]))
print('-'.join(li[:0:-1]))
print('-'.join((li[1:][::-1])))
(5) for循环
names = ["粉丝", "粉条", "粉带"]
for name in names:
print(f"猫猫叫:{name}" )
3. 列表的常用方法
(1) 一次添加一个元素
li = [1, 2, 3]
li.append(4)
print(li)
输出结果: [1, 2, 3, 4]
(2) 增加列表的内容
- 一次追加多个元素
li = [1, 2, 3]
li.append([4,5,6])
print(li)
输出结果: [1, 2, 3, [4, 5, 6]]
list1 = [1, 2, 3]
list1.extend([4,5,6])
print(list1)
输出结果: [1, 2, 3, 4, 5, 6]
- 在列表开头添加
list2 = [1, 2, 3]
list2.insert(0,"cat")
print(list2)
输出结果: ['cat', 1, 2, 3]
- 在指定索引前面加dog
list3 = [1, 2, 3]
list3.insert(2,"dog")
print(list3)
输出结果: [1, 2, 'dog', 3]
(3) 修改列表内容:通过索引和切片重新赋值的方式
list = [1, 2, 3]
list[0] = "cat" #通过索引的方式修改
list[-1] = "dog"
print(list)
list[:2] = ["pink","black"] #通过切片的方式修改
print(list)
输出结果:
['cat', 2, 'dog']
['pink', 'black', 'dog']
(4) 查看:通过索引和切片查看元素
原理:查看索引值和出现的次数
li =[1,2,3,1,1,2,3]
print(li.count(1)) #计算1出现了几次
print(li.index(2)) #查找2第一次出现时的索引值
(5) 删除列表中某元素
- 根据索引删除
li = [1,2,3]
delete_num = li.pop(1) #若不写索引值,默认为最后一个
print("删除的元素是:",delete_num) # 删除的元素是: 2
print(li) #[1, 3]
- 根据valuse值删除
li = [1,2,3]
li.remove(1)
print(li) #[2, 3]
- 全部清空
li = [1,2,3]
li.clear()
print(li) #输出 []
4. 列表的翻转,排序,拷贝功能
li = [18,6,56,32]
li.reverse() #类似于 [::-1],具有反转的功能
print(li) #[32, 56, 6, 18]
#sort排序默认由小到大,如果想由大到小排序,需设置reverse=true
li.sort(reverse=True) #按照由大到小排列
print(li) #[6, 18, 32, 56]
#拷贝
li1 = li.copy()
print(id(li),id(li1)) #打印内存信息
print(li,li1)
三、元组tuple的操作(戴了紧箍咒的列表,不能修改元素)
1. 元组的创建
>>> t1 =() #空元组
>>> print(t1,type(t1))
() <class 'tuple'>
>>> t1 =(1)
>>> print(t1,type(t1)) # 只有单个元素不是元组
1 <class 'int'>
>>> t1 =(1,)
>>> print(t1,type(t1)) #元组只有一个元素的时候一定要加逗号
(1,) <class 'tuple'>
>>> t1 =(1,1.2,True,[1,1,3])
>>> print(t1,type(t1))
(1, 1.2, True, [1, 1, 3]) <class 'tuple'>
2. 元组的特性
拼接
>>> print((1,2,3)+(1,))
(1, 2, 3, 1)
>>> print((1,2,3)*5)
(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> print(1 in (1,2,3))
True
>>> t = (1,2,3,4)
>>> print(t[0])
1
>>> print(t[-1])
4
>>> print(t[::-1])
(4, 3, 2, 1)
>>> print(t[:2])
(1, 2)
>>> print(t[1:])
(2, 3, 4)
>>>
3. 常用方法
元组是不可变数据类型,不能增删改,只能查看
# 通过索引和切片查看元素
>>> t=(1,2,3,1,1,3)
>>> print(t.count(3))
2
>>> print(t.index(3))
2
四、 命名元组的使用
# 从collections模块导入namedtuple工具
from collections import namedtuple
#创建命名元组User
User = namedtuple('User', ("name", "age", "city"))
#给命名元组传值
user1 = User("westos", 18, "西安")
#打印命名元组
print(user1)
#获取命名元组指定的信息
print(user1.name)
print(user1.age)
print(user1.age)
练习
from collections import namedtuple
menu = """
云主机管理系统
1). 添加云主机(IP,hostname,IDC)
2). 搜索云主机(IP搜索)
3). 删除云主机
4). 云主机列表
5). 退出系统
请输入你的选择:"""
hosts = []
Host =namedtuple('Host', ('ip', 'hostname', 'idc'))
while True:
choice = input(menu)
if choice == "1":
print("添加云主机".center(50, '*'))
ip = input("请输入IP地址:")
hostname = input("请输入正确的主机名:")
idc = input("请输入idc(eg:ali,huawei...)名称:")
Host1 = Host(ip, hostname, idc)
hosts.append(Host1)
print(f"添加{idc}的云主机成功,IP地址为{ip}")
elif choice == "2":
print("搜索云主机".center(50, '*'))
ip = input("请输入需要搜索的主机IP:")
for host in hosts:
if ip == host.ip:
print(f"{host.ip}\t{host.hostname}\t{host.idc}")
break
else:
print("请输入正确的IP地址")
elif choice == '3':
print("删除云主机".center(50, "*"))
ip = input("请输入需要删除的主机IP:")
for host in hosts:
if ip == host.ip:
hosts.remove(host)
elif choice == "4":
print("云主机列表".center(50, '*'))
count =0
print("IP\t\t\thostname\t\tidc")
for host in hosts:
count += 1
print(f'{host.ip}\t\t{host.hostname}\t\t\t{host.idc}')
print("主机总个数为:", count)
elif choice == '5':
print("系统正在退出,欢迎下次使用....")
exit()
else:
print("请输入正确的选项")
五、地址引用和深拷贝和潜拷贝
1. 数据类型分类
- 不可变数据类型: 数值,字符串str,tuple,nametuple
- 可变数据类型(可增删改) :list
2. 值得引用
- nums1和nums2指向同一个内存空间(=)
nums1 = [1, 2, 3]
nums2 = nums1
nums1.append(4)
print(nums2) #结果输出为[1, 2, 3, 4]
3. 潜拷贝
- 对内存地址的拷贝,n1 n2指向同一个内存地址,修改n1会影响n2(li.copy(),copy.copy)
n1 = [1, 2, 3]
n2 =n1.copy() #n1.copy()和n1[:]都可以实现拷贝
print(id(n1), id(n2)) #1879038751488 1879038753920
n1.append(4)
print(n2) #[1, 2, 3]
潜拷贝:
n1 = [1, 2, [1, 2]]
n2 = n1.copy()
n1[-1].append(4)
print(n2)
print(id(n1), id(n2))
print(id(n1[-1]), id(n2[-1]))
输出结果:
[1, 2, [1, 2, 4]]
2981595640768 2981595640576
2981595640704 2981595640704
4. 深拷贝
如果列表的元素包含可变数据类型(可增删改:list) ,一定要用深拷贝!!!!
- 拷贝另外一个变量的值,n1 n2的内存地址不同,修改n1并不会影响n2(copy.deepcopy())
import copy
n1 = [1, 2, [1, 2]]
n2 = copy.deepcopy(n1)
n1[-1].append(4)
print(id(n1), id(n2))
print(id(n1[-1]), id(n2[-1]))
print(n2)
输出:2350387450944 2350388443776
2350387805824 2350388443136
[1, 2, [1, 2]]
5. 浅拷贝与深拷贝的区别
最根本的区别在于是否真正获取一个对象的复制实体,而不是引用
假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着变了,说明是潜拷贝,拿人手短(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力(修改堆内存中的不同的值)