7.列表推导式,深浅copy,元组字典和集合

列表的嵌套

names = ['刘德华', ['蔡徐坤', ['鹿晗', '黄子韬'], '肖战']]  #注意都是使用的下标
print(names[1][1][1])   #黄子韬
names[1][2] = 'jay'   #['刘德华', ['蔡徐坤', ['鹿晗', '黄子韬'], 'jay']]
print(names)
#用列表,,三个教室,,九个老师,随机分配到三个教室内
teacher_names = ['001', '002', '003', '004', '005', '006', '007', '008', '009']
rooms = [[], [], []]   # 创建三个教室
for i in teacher_names:
    rooms_name = random.randint(0, 2) #随机在0.1.2三个教室中生选择一个,等着被赋值
    rooms[rooms_name].append(i)             #调用教室,赋值
                                            #rooms[rooms_name],就是调用!!调用!!!0.1.2三个教室中的第几个,等着放置内容
                                            #.append(i)就是吧第几个老师,放在了随机的第几个教室里面
print(rooms)

列表推导式

所谓的列表推导式,就是指的轻量级循环创建列表

#生成一个有序列表  常规
a = []
for i in range(10):
    a.append(i)
print(a)    #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

"""
快速生成一个列表方法
吧上面的式子浓缩一下 a = [a.append(i) for i in range(10)],同时都已经在a[]中了,所以a.append[i]就不需要了,所以最后变成了  a = [i for i in range(10)]
"""
a = [i for i in range(10) if i % 2 == 0]    
print(a)  #0 . 2 . 4 . 6 . 8 
#上面的简写具体为
a = []
for i in range(10):   # 这里输出02468,也可以写为for i in range(10, 2):    a.append(i)
    if i % 2 == 0
    a.append(i)
print(a)
x = [[a, (b, c)] for a in range(2) for b in range(3) for c in range(4)]   #元组列表都可以放

print(x)   
"""得到
[[0, (0, 0)], [0, (0, 1)], [0, (1, 0)], [0, (1, 1)], [1, (0, 0)], [1, (0, 1)],
[1, (1, 0)], [1, (1, 1)]]
 """
# 请写出一段 Python 代码实现分组一个 list 里面的元素,比如 [1,2,3,...100]变成 [[1,2,3],[4,5,6]....]
a = [x for x in range(1, 101)]
b = [a[i:i + 3] for i in range(0, len(a), 3)]

#原式为
a = [x for x in range(0, 101)]    #a的数值为0- 100的一个列表
b = []                              #b为外层的大列表
for i in range(0, len(a), 3):   # 3表示,隔三个数字输出一次   i为0,3,6,9,12这样子,为了方便后面对a的切片
    b.append(a[i: i+3])        #对a切片,每次切[i: i+3]  插入b中    ,注意切片包头不包尾
                     #这里是因为i从0开始,每次三个[0 :3 ]为0.1.2,,就会每次给b赋值a[0],a[1],a[2]
                     #也就是a[i],a[i+1],a[i+2],而i的值为0.3.6.9,所以会切片出a[0: 3],a[6: 9]
                     #a[10: 13]这样的也就是刚好三个一组
print(b)

copy

浅copy

重点就是公用指引!!!,共用指引,改了一个,a,b两个列表的值都会改动,但是没有共用指引,就不会互相影响
在这里插入图片描述

words2 = a.copy() 浅copy 就是b复制了a的第一层指引 a的第一层指引就是画了一个黑坨坨的地方,b复制的一层指引就是一个空心的坨坨,因为a.b在指向一维数组[ 3, 4] 的时候,ab公用了a的二层指引…(就是中间两个空格子指向左边数字3.4就是a的二层指引) , , ,所以,当b执行b[2].[0] = '222’时,ab在数值3上的公共指引被改成了指向222,所以b的值这个时候和a一样都成了 [‘1’, ‘2’, [‘222’, ‘4’], ‘5’] ,也就是这样,a的数值也变了,

但是,当执行b[0] = '111’时,因为ab并未公用同一个指引,所以a在a[0]上的值未发生改变

import copy  #导入copy
a = ['1', '2', ['3', '4'], '5']			#对应上图的12345
b = copy.copy(a)
b[0] = '111'
b[2][0] = '222'
print(a)  # ['1', '2', ['222', '4'], '5']
# a 里的 3 被修改成了 222
#解释为啥a,也会被改变
print(b)  # ['111', '2', ['222', '4'], '5']
# b 里的 1 被修改成了 111,,同时3被修改成了 222

深copy

深copy会把所有指引都赋值一遍,没有公共指引,.,没有公共指引!!!不会互相影响

在这里插入图片描述

黑球是a的指引,一个黑球代表一层,空心球代表b的指引,完全的复制了b的一份,

这样一来,不管b如何去改变自己的指引,a不会有任何变化

元组

元组名 = (1,2,3...)
定义单元素元组  格式:nums = (12,)
空元组如何定义: 元组名 = ()

Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。()

说明: python中不允许修改元组的数据,包括不能删除其中的元素。

# 所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
# 可变类型(修改数据,内存地址不会发生变化)有: 列表、字典、集合
# 不可变类型(修改数据,内存地址必定发生变化)有: 数字、字符串、元组
tuples = (True, 'hello', 12, 13.5)   #创建元组
print(tuples[0])			#输入元组中下标为0的数
nums = (12,)				#创建一个只有一个元素的元组
names = ()					#创建一个空元祖
print(type(names))

count, index

index和count与字符串和列表中的用法相同

index(“目标字符串” , start , end) !!!包头不包尾!!! 查询字符串是否存在,返回下标,不存在就报错

count () 查询某一字符在一字符创中出现多少次

a = ('a', 'b', 'c', 'a', 'b')
b = a.index('c', 0, 3) # 注意是左闭右开区间
print(b)

a = ('a', 'b', 'c', 'a', 'b')
print(a.count('c'))

字典

当存储的数据要动态添加、删除的时候,用列表会很不方便,因为每次添加数组,数组下标就会变化,总要重新记忆,

所以就用到了字典

定义字典的格式:{键1:值1, 键2:值2, 键3:值3, …, 键n:值n}

stus = {'name': '胡冠雨', 'age': 30,'height': '150cm'}
print(stus.get('height'))
stus['height'] = '180cm'   #修改键height的值 为  180cm
print(stus.get('height'))
stus['weight'] = '150斤'   #修改键weight的值 为  150斤
print(stus)

说明:

  • 字典和列表一样,也能够存储多个数据
  • 列表中找某个元素时,是根据下标进行的;字典中找某个元素时,是根据’名字’(就是冒号:前面的那个值,例如上面代码中的’name’、‘id’、‘sex’)
  • 字典的每个元素由2部分组成,键:值。例如 ‘name’:‘班长’ ,'name’为键,'班长’为值
  • 键可以使用数字、布尔值、布尔值、元组等不可变数据类型,但是一般习惯使用字符串
  • 每个字典里的key都是唯一的,如果出现了多个key,后面的value会覆盖前一个key对应的value.

在习惯上:

  • 列表更适合保存多个商品、多个姓名、多个时间,这样的相似数据;
  • 字典更适合保存一个商品的不同信息、一个人的不同信息,这样的不同数据
  • 列表重一层数据,字典重多层数据

添加

如果在使用 变量名[‘键’] = 数据 时,这个“键”在字典中,不存在,那么就会新增这个元素,查询的时候查不到就是添加

info = {'name':'班长'}
print('添加之前的字典为:%s' % info)
info['id'] = 100  # 为不存在的键赋值就是添加元素
print('添加之后的字典为:%s' % info)
#添加之前的字典为:{'name': '班长'}
#添加之后的字典为:{'name': '班长', 'id': 100}

删除

  1. del()
  2. clear()
# del 删除指定的元素   del info['name']
info = {'name':'班长', 'id':100}
print('删除前,%s' % info)
del info['name']  # del 可以通过键删除字典里的指定元素
print('删除后,%s' % info)

#del 直接删除整个字典..从地址上删除的那种   del info
print('删除前,%s' % info)
del info  # del 也可以直接删除变量
print('删除后,%s' % info)
# clear()  清空这个字典中的所有元素值  最后只剩下一个{}
info = {'name':'monitor', 'id':100}
print('清空前,%s'%info)
info.clear()
print('清空后,%s'%info)
#清空前,{'name': 'monitor', 'id': 100}
#清空后,{}

查询

除了使用key查找数据,还可以使用get来获取数据

  1. print(info[‘age’]) # 获取年龄 没有则报错
  2. info.get(‘sex’) # 获取性别, 没有也不会报错
  3. info.get(‘sex’ , ‘男’) # 获取性别, 没有就会提供一个默认值
info = {'name': '班长', 'age': 18}
print(info['age'])  # 获取年龄
# print(info['sex']) # 获取不存在的key,会发生异常  报错

print(info.get('sex'))  # 获取不存在的key,获取到空的内容,不会出现异常
print(info.get('sex', '男'))  # 获取不存在的key, 可以提供一个默认值。注意,获取默认值不会修改字典内容。
#18   None  男

修改

字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改

info = {'name':'班长', 'id':100}
print('修改之前的字典为 %s:' % info)
info['id'] = 200  # 为已存在的键赋值就是修改
print('修改之后的字典为 %s:' % info)
#修改之前的字典为 {'name': '班长', 'id': 100}:
#修改之后的字典为 {'name': '班长', 'id': 200}:

遍历

注意只可以根据键找对应的值,不能用值找键,因为键唯一,值不唯一

stus = {'name': '胡冠雨', 'age': '30', 'height': '150cm'}
# 1.那所有的键
for i in stus.keys():
    print(i + "--" + stus.get(i))
print('-' * 20)
		#name--胡冠雨
		#age--30
		#height--150cm
        
# 2.直接遍历所有的值
for i in stus.values():
    print("直接遍历所有的值"+i)
    	#胡冠雨
		#30
		#150cm

# 3.遍历键值对  然后获取键和值  
#items方法就是把内部打包成了元组
for key, value in stus.items():
    print("直接遍历所有的键值对"+key + "--" + value)
#上面这个用items的方法也可以写成,但是字符没有明显区分(可以用字符串区分,我还没有)
for i in stus.items():
    print(i)
   	 	#name--胡冠雨
		#age--30
		#height--150cm

练习

# 有一个列表persons,保存的数据都是字典
# 要求让用户输入一个姓名,如果这个姓名在列表里存在,
# 就提示用户名称已存在,添加失败;如果这个姓名在列表里不存在,
# 提示让用户输入年龄,并将用户输入的姓名和年龄添加到这个列表里。

# 1.先考虑如何获取到列表中所有的字典  for
# 2.根据for循环出来的数据  判断姓名是否存在
# 3.如果存在  添加失败   如果不存在  继续输入年龄  然后保存到列表中
persons = [{'name': 'zhangsan', 'age': 18}, {'name': 'lisi', 'age': 20}]

# 定义一个存储名字的列表
names = []

# 将所有的名字取出来放到names列表中
for i in persons:
    names.append(i['name'])

while True:
    name = input("请输入用户名:")
    if name not in names:
        age = input("请输入年龄:")
        per = {'name': name, 'age': age}

        persons.append(per)
        break
    else:
        print("用户名已经存在")

print(persons)
# 'aabbccddeeeeffff'  统计每个字母出现的次数
'''
先将字符串遍历  拿着每一次遍历的结果区字典中判断是否存在对应的键
如果不存在  直接把字母当键存进去  把1当值存进去

如果存在  把值先取出  再+1  然后再存入
'''
s = 'aabbccddeeeeffff'
counts = {}
for i in s:
    # 判断i是否在空字典中已经存在
    # 如果不存在  就直接存键值对  键是i  值是1
    if not counts.get(i):
        counts[i] = 1
    else:
        # 如果i存在  那就先把值取出然后+1 再赋值给字典中的i键
        num = counts[i] + 1
        counts[i] = num
print(counts)

集合

集合(set)是一个无序的不重复元素序列,可以使用大括号 { } 或者 set() 函数创建集合。

这里的无序指代存入和取出顺序不一致,注意哦,是存入和取出顺序不一致,并不是指的排序

但是数字会从集合中从小到大排序,其他的不会

注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

增加

s.add(x) 如果元素已存在,则不进行任何操作

s.update( x ) 可以添加元素,且参数可以是列表,元组,字典等…值可以有多个,用逗号分开

​ 这里注意updatte只可以增加可迭代的东西,就是可遍历的,并且不能只放一个元素

删除

s.remove( x ) 如果元素不存在,则会发生错误。

s.discard( x ) 如果元素不存在,不会发生错误

s.pop() 可以设置随机删除集合中的一个元素,全是数字的集合.只会踢掉头,列表就是尾,其他的就是随机的了

常见方法

方法描述
add()为集合添加元素
clear()移除集合中的所有元素
copy()拷贝一个集合
pop()随机移除元素
remove()移除指定元素
union返回两个集合的并集
update()给集合添加元素
difference()返回多个集合的差集
difference_update()移除集合中的元素,该元素在指定的集合也存在。
discard()删除集合中指定的元素
intersection()返回集合的交集
intersection_update()删除集合中的元素,该元素在指定的集合中不存在。
isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
issubset()判断指定集合是否为该方法参数集合的子集。
issuperset()判断该方法的参数集合是否为指定集合的子集
symmetric_difference()返回两个集合中不重复的元素集合。
symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。

练习逆置

有一个无序且元素数据重复的列表nums, nums=[5,8,7,6,4,1,3,5,1,8,4],对这个列表里的元素去重,并进行降序排序。

"""
a.reverse()  # 逆置,不排序
a.sort()  # 默认从小到大排序
a.sort(reverse=True)  # 从大到小排序
"""
# 方法一:调用列表的sort方法
nums = [5, 8, 7, 6, 4, 1, 3, 5, 1, 8, 4]
nums2 = list(set(nums))
nums2.sort(reverse=True)
print(nums2)

# 方法二:使用sorted内置函数
print(sorted(list(set(nums)), reverse=True))

#{'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 4, 'f': 4}
#[8, 7, 6, 5, 4, 3, 1]
#[8, 7, 6, 5, 4, 3, 1]

a.reverse() # 逆置,不排序
a.sort() # 默认从小到大排序
a.sort(reverse=True) # 从大到小排序
“”"

方法一:调用列表的sort方法

nums = [5, 8, 7, 6, 4, 1, 3, 5, 1, 8, 4]
nums2 = list(set(nums))
nums2.sort(reverse=True)
print(nums2)

方法二:使用sorted内置函数

print(sorted(list(set(nums)), reverse=True))

#{‘a’: 2, ‘b’: 2, ‘c’: 2, ‘d’: 2, ‘e’: 4, ‘f’: 4}
#[8, 7, 6, 5, 4, 3, 1]
#[8, 7, 6, 5, 4, 3, 1]










































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值