元组
-
概念:
和列表相似,本质上是一种有序 的集合
-
元组和列表的不同之处:
- 1、表示方法:列表:[] 元组:()
- 2、列表中的元素可以进行增加和删除操作,但是,元组中的元素不能修改【元素:一旦被初始化,将不能发生改变】
- 3、列表中有一个元素和元组中有一个元素表示方法不一样:列表[元素1],元组(元素1,)
- 4、定义不同:
列表 |
是一种有序的,可变的,可以存储重复元素的,可以存储不同类型数据的集合 |
元组 |
是一种有序的,不可变的,可以存储重复元素的,可以存储不同类型数据的集合 |
- 元组关键字:tuple( 列表关键字:list) 【tuple n. [计] 元组,重数】
'''
创建列表:
创建空列表:list1 = []
创建有元素的列表:list1 = [元素1,元素2,。。。。。]
创建元组
创建空元组:tuple1 = ()
创建有的元组:tuple1 = (元素1,元素2,。。。。)
'''
#1、关键字
list1 = [34,5,6,6,6,6,6,"abc"]
print(list1,type(list1)) #[34, 5, 6, 6, 6, 6, 6, 'abc'] <class 'list'>
tuple1 = (34,6,7,7,7,7,7,"abc")
print(tuple1,type(tuple1)) #(34, 6, 7, 7, 7, 7, 7, 'abc') <class 'tuple'>
#2、当元组中只有一个元素时,则需要在元素的后面添加逗号,否则会有歧义。
list2 = [45]
print(list2,type(list2))
tuple2 = (45)
print(tuple2,type(tuple2)) #45 <class 'int'>
tuple2 = ("45")
print(tuple2,type(tuple2)) #45 <class 'str'>
tuple2 = (45,)
print(tuple2,type(tuple2)) #(45,) <class 'tuple'>
#3、列表可变,元组不可变
list1[1] = 100
print(list1)
# tuple1[1] = 100 # TypeError: 'tuple' object does not support item assignment
#4、在元组中的列表是可变的,因为列表是可变的
t1 = (34,4,5,[45,5,78])
t1[-1][0] = 100
print(t1) # (34, 4, 5, [100, 5, 78])
print("#" * 50)
#5、元组与列表相同的操作(注意,+操作和 *操作以及切片操作相当于产生新元素,并非修改元组)
# a.+
t1 = (1,2)
t2 = (3,4)
print(t1 + t2) #(1, 2, 3, 4)
# b.*
print(t1 * 3) #(1, 2, 1, 2, 1, 2)
# c.in和not in
print(2 in t1) #True
print(23 not in t1) #True
# d.切片[star:end:step]注意:end取不到,理解:左闭右开
t1 = (11,22,33,44,55,66,77,88,99)
print(t1[100:]) # ()
print(t1[0:-1]) # (11.....88)
print(t1[1:5:-1]) # ()
print(t1[-1:-5:-1]) # (99,88....66)
print(t1[-5:-1:-1]) # ()
print(t1[3::-1]) # (44...11)
print('*' * 40)
#6.元组遍历(1、直接遍历元组;2、通过元组元素索引遍历;3、enumerate(元组名),转化为枚举遍历索引和元素)
t1 = (11,22,33,44,55,66,77,88,99)
for ele in t1: #直接遍历元素
print(ele,end=' ')
print()
for i in range(len(t1)): #索引遍历
print(t1[i],end='//')
print()
for i,num in enumerate(t1): #枚举遍历 【enumerate vt. 列举;枚举;】
print(i,num,end="||")
print()
'''
11 22 33 44 55 66 77 88 99
11//22//33//44//55//66//77//88//99//
0 11||1 22||2 33||3 44||4 55||5 66||6 77||7 88||8 99||
'''
print('*' * 40)
#7、系统功能【python自带,不用导入模块】
t1 = (11, 22, 33, 44, 55, 66, 77, 88, 99)
# a.
print(len(t1)) #9
# b
print(t1.index(44)) #3
# c.
print(t1.count(22)) #1 【count v. (按顺序)数数;计数】
# d.
print(max(t1)) #99
print(min(t1)) #11
# e.list()和tuple(),列表和元组之间可以相互转换
l1 = [34, 6]
print(l1, type(l1)) #[34, 6] <class 'list'>
t1 = tuple(l1)
print(t1, type(t1)) #(34, 6) <class 'tuple'>
l2 = list(t1)
print(l2, type(l2)) #[34, 6] <class 'list'>
字典
- 相关概念:列表和元组的使用缺点:当存储的数据要动态添加、删除的时候,我们一般使用列表,但是列表有时会遇到一些麻烦,缺点:定位元素比较麻烦。既能存储多个数据,还能在访问元素的很方便的定位到需要的元素,采用字典。
- 字典的定义:
1、语法:{键1:值1, 键2:值2, 键3:值3, …, 键n:值n}
2、字典和列表类似,都可以用来存储多个数据
3、在列表中查找某个元素时,是根据下标进行的;字典中找某个元素时,是根据键(key)查找的
4、字典中的每个元素都由两部分组成,键:值。例如 ‘name’:‘班长’ ,'name’为键,'班长’为值
5、键只能使用数字、布尔值、元组,字符串等不可变数据类型,但是一般习惯使用字符串,切记不能使用列表等可变数据类型,值的数据类型没有限制。
不可变的数据类型: |
int float bool str tuple |
可变的数据类型: |
list dict set |
- 注意:
1、每个字典里的key都是唯一的,如果出现了多个相同的key,后面的value会覆盖之前的value,但是字典中的值可以不唯一,设计一种数据结构和应用场景有很大关系,例如现实中一般代表个性的表征不能重复例如学号(键),但考试成绩可以重复(值)。
2、字典本身是可变数据类型。
3、python在3.7版本之前字典是无序的,3.7以后是有序的
4、有六种生成字典的方法
'''
#字典:
#一、字典生成
'''
#1、字典定义(1、传统定义法;2、空字典增加法(利用字典的可变性);3、系统方法dict(key1=value1,.....);
#4、系统方法dict([(key1,value1),(key2,value2)......]) );5、dict(zip([key1,key2.....],[value1,value2.....]))
# 1.传统定义法 *****
dict1 = {'name':'张三','age':18}
print(dict1)
# 2.空字典增加法 *****
dict2 = {}
dict2['aaa'] = 10
dict2['bbb'] = 20
print(dict2)
# 3.dict(key1=value1,key2=value2.....)
dict3 = dict(x=23,y=56,z=10)
print(dict3) #{'x': 23, 'y': 56, 'z': 10}
dict31 = {10:0,20:1,30:2}
print(dict31)
# 注意:使用dict(key1=value1...)定义的字典,key只能是不可变数据,一般是字符串
# dict32 = dict(10=0,20=1,30=2)
dic = {(1,):7,(2,):4}
print(dic) #{(1,): 7, (2,): 4}
print(dic[(1,)]) #7
# 4.dict([(key1,value1),(key2,value2)......])
# 列表是可变的,元组是不可变的,就是说键值对个数可变,但键值对因为键的不可变特性,所以不可变。
dict4 = dict([('abc',100),('hello',200)])
print(dict4)
# 注意:下面三种写法可以使用,但是不规范
# dict4 = dict([['abc',100],['hello',200]])
# print(dict4)
# dict4 = dict((('abc',100),('hello',200)))
# print(dict4)
# dict4 = dict((['abc',100],['hello',200]))
# print(dict4)
# 5.dict(zip([key1,key2.....],[value1,value2.....])) *******
dict5 = dict(zip(['zhangsan','jack','tom'],[12,20,15])) #列表作为zip元素
print(dict5)
dict5 = dict(zip(('zhangsan','jack','tom'),(12,20,15))) #元组作为zip元素
print(dict5)
dict5 = dict(zip(['zhangsan','jack','tom','bob'],[12,20,15])) #一个长,一个短,生成多少键值对,以短的为准
print(dict5)
dict5 = dict(zip(['zhangsan','jack','tom'],[12,20,15,30])) #一个短,一个长,生成多少键值对,以短的为准
print(dict5)
# 6.字典推导式
dict2 = {i:i**2 for i in range(1,5) if i % 2 == 0}
print(dict2) #{2: 4, 4: 16}
#=======================================================================================================================
#二、字典的基本使用
#1、{}
l1 = [34,5,6]
print(l1,type(l1))
t1 = (34,5,6)
print(t1,type(t1))
d1 = {'a':10,'b':20}
print(d1,type(d1))
s1 = {34,6,67,7,7} # 集合:无序,去重
print(s1,type(s1))
#2、空字典,空列表、空元组、空集合
print(type({})) #<class 'dict'> 注意:字典和集合都是使用{}表示的,但是空{}默认表示字典
b = []
print(b,type(b)) # 空列表 [] <class 'list'>
c = ()
print(c,type(c)) # 空元组 () <class 'tuple'>
d = set()
print(d,type(d)) # 空集合 set() <class 'set'>
#3、字典中键值的注意事项
# a.字典中的键只能是不可变的数据类型,常用字符串
"""
不可变的数据类型:int float bool str tuple
可变的数据类型:list dict set
"""
dict1 = {10:23,45.4:10,True:100,'abc':45,(1,2):56}
print(dict1)
# dict1 = {10:23,45.4:10,True:100,'abc':45,(1,2):56,[3,4]:34}
# print(dict1)
# b.字典中的值可以是任意的数据类型
dict2 = {1:10,2:34.5,3:False,4:'abc',5:[34,56],6:(345,6)}
print(dict2)
# c.字典中的键是唯一的,值可以重复
# 注意:字典的所有的键相当于一个集合【集合不允许存储重复元素】
# 字典的所有的值相当于一个列表【列表允许存储重复元素】
# 如果一个字典中出现了多个相同的key,后面的value会覆盖之前的value
dict3 = {'name':'赵四','age':18,'name':'jack'}
print(dict3)
dict3 = {"小明":66,"小花":100,"jack":70,"tom":70,"bob":99}
print(dict3)
#4、字典中键值的访问(1、键访问;2、系统.get(key,default);3、修改key值(存在修改,不存在尾部添加))
"""
注意:
a.字典中的键相当于列表中的索引,列表中通过索引访问元素,字典中通过键访问对应的值
b.字典是可变的数据类型,可以通过键将原值获取出来,然后进行修改
"""
# 1.通过键获取值
# a.语法一:字典[键],注意:键一定要存在,才能获取到对应的值
info_dict = {'name':'jack','age':10,"gender":'male'}
age = info_dict['age']
print(age) #10
# 注意:如果访问一个不存在的key,则报错KeyError: 'hobby'
# hobby = info_dict['hobby']
# print(hobby)
# 优化
key = 'hobby'
if key in info_dict:
hobby = info_dict['hobby']
print(hobby)
else:
print(f"{key}不存在")
#
# b.语法二:字典.get(key,default),如果键存在,则获取对应的值; ******
# 1>default省略,如果键不存在,默认获取到的None
print(info_dict.get('age'))
print(info_dict.get('hobby'))
# 2>【了解】default不省略,如果键不存在,获取到的default
print(info_dict.get('age',66))
print(info_dict.get('hobby','dance'))
#
# 2.通过键修改值
# 注意:字典是可变的数据类型,其中的值可以随时被修改,但是键不能被修改
info_dict = {'name':'jack','age':10,"gender":'male'}
print(info_dict) #{'name': 'jack', 'age': 10, 'gender': 'male'}
# a.如果键存在,字典[键] = 值,表示修改指定键对应的值
info_dict['name'] = 'hello'
print(info_dict) #{'name': 'hello', 'age': 10, 'gender': 'male'}
# b.如果键不存在,字典[键] = 值,表示将指定的键值对添加到字典尾部 ******
info_dict['score'] = 100
print(info_dict) #{'name': 'hello', 'age': 10, 'gender': 'male', 'score': 100}
#5、遍历字典(1、字典名遍历key值;2、系统key();3、系统values();4、系统items()(同时获取key和value))
info_dict = {'name':'jack','age':10,"gender":'male'}
# 1.获取key ******
for key in info_dict:
print(key,info_dict[key])
# 2.获取key
# print(info_dict.keys()) # 获取字典中所有的键
for key in info_dict.keys(): #和1等效
print(key,info_dict[key])
# 3.获取value
print(info_dict.values()) # 获取字典中所有的值
for value in info_dict.values():
print(value)
"""
注意:
a.通过key获取value,语法:字典[key]
b.通过value获取key,无法直接获取,只能通过循环遍历
c.在字典中,通过key获取到的value是唯一的,但是,通过value获取到的key不一定唯一
"""
# 4.获取key和value *******
# print(info_dict.items()) # 获取字典中的键值对
for key,value in info_dict.items():
print(key,value)
# a,b = (23,5) # 拆包
# print(a,b)
#6、字典推导式
"""
列表推导式:[元素的规律 for循环 if语句]
字典推导式:{key:value for循环 if语句}
"""
# 1.【面试题】已知一个字典{'a':10,'b':20},实现程序,交换key和value,生成一个新的字典
dict1 = {'a':10,'b':20}
# 方式一
dict2 = {}
for key,value in dict1.items():
dict2[value] = key
print(dict2)
# 方式二
dict2 = dict(zip(dict1.values(),dict1.keys()))
print(dict2)
# 方式三
dict2 = {value:key for key,value in dict1.items()}
print(dict2)
# 2.生成一个字典{1:1,3:9,5:25,7:49,9:81}
# 方式一
dict21 = {n:n ** 2 for n in range(1,10,2)}
print(dict21)
# 方式二
dict22 = {n:n ** 2 for n in range(1,10) if n % 2 == 1}
print(dict22)
# 3.【面试题】
list3 = [m + n for m in 'abc' for n in '123']
print(list3) # 9 ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
dict3 = {m:n for m in 'abc' for n in '123'}
print(dict3) # 3 {'a': '3', 'b': '3', 'c': '3'}
#=======================================================================================================================
#三、字典系统功能
# 一、增(1、key的特性;2、系统功能update(字典);3、系统功能setdefault(key,default))
dict1 = {'a':10,'b':20}
print(dict1) #{'a': 10, 'b': 20}
# 1.字典[key] = value,当key不存在时,表示增加键值对 *****
dict1['c'] = 30
print(dict1) #{'a': 10, 'b': 20, 'c': 30}
# 2.update():更新,合并字典,将指定字典中的键值对添加到原字典中 ******主要会出现在面试题中
# dict1.update(dict2):将dict2字典中的键值对添加到dict1中
new_dict = {'x':34,'y':75}
dict1.update(new_dict)
print(dict1) #{'a': 10, 'b': 20, 'c': 30, 'x': 34, 'y': 75}
print(new_dict) #{'x': 34, 'y': 75}
#new_dict.update('j':90) #SyntaxError: invalid syntax 【update中放的是要添加的字典】
new_dict.update({'j': 90})
print(new_dict) #{'x': 34, 'y': 75, 'j': 90}
# 3.setdefault(key,default):通过设置默认值的方式增加键值对,了解
dict1 = {'a':10,'b':20}
print(dict1) #{'a': 10, 'b': 20}
# a.default省略,则向指定字典中添加:key:None
dict1.setdefault('abc')
print(dict1) # {'a': 10, 'b': 20, 'abc': None}
dict1.setdefault('123',9)
print(dict1) #{'a': 10, 'b': 20, 'abc': None, '123': 9}
# b.default未省略,则向指定字典中添加:key:default
dict1.setdefault('xyz',88)
print(dict1) # {'a': 10, 'b': 20, 'abc': None, '123': 9, 'xyz': 88}
# 二、删(1、系统功能pop(key);2、系统功能popitem();3、系统功能clear();4、系统功能del 删除元素)
# 1.pop(key):弹出,删除指定key对应的键值对, ********
# 【实际工作原理:将指定键值对从字典中移除,但是键值对在内存中】
dict1 = {'name':"张三",'age':18,'hobby':"篮球"}
print(dict1)
r = dict1.pop('age') # pop跟列表中的用法类似,返回被删除的数据,age相当于索引,返回的是键值对当中的值
print(dict1) #{'name': '张三', 'hobby': '篮球'}
print(r) #18
# 2.popitem():在Python3.7之前,表示随机删除一对,在3.7之后,删除最后一对,因为3.7之前字典是无序的。
dict1 = {'name':"张三",'age':18,'hobby':"篮球"}
print(dict1) #{'name': '张三', 'age': 18, 'hobby': '篮球'}
dict1.popitem()
print(dict1) #{'name': '张三', 'age': 18}
# 3.clear(),只清除,字典还在,但为空。
dict1 = {'name':"张三",'age':18,'hobby':"篮球"}
print(dict1) #{'name': '张三', 'age': 18, 'hobby': '篮球'}
dict1.clear()
print(dict1) #{}
# 4.del,删除字典,字典也会被删除,在内存中不存在
dict1 = {'name':"张三",'age':18,'hobby':"篮球"}
print(dict1)
del dict1['age']
print(dict1) #{'name': '张三', 'hobby': '篮球'}
del dict1
#print(dict1) #(del dict1 ----删除字典)NameError: name 'dict1' is not defined
# 三、改(就用key的特性:不存在,就在字典末尾添加,存在覆盖)
dict1 = {'name':"张三",'age':18,'hobby':"篮球"}
print(dict1) #{'name': '张三', 'age': 18, 'hobby': '篮球'}
dict1['age'] = 66
print(dict1) #{'name': '张三', 'age': 66, 'hobby': '篮球'}
dict1['jj'] = 88
print(dict1) #{'name': '张三', 'age': 66, 'hobby': '篮球', 'jj': 88}
# 四、查(1、系统功能len、2、系统功能keys、4、系统功能valuses、5、系统功能items)
print(len(dict1)) #4 获取键值对的对数
print(dict1.keys()) #dict_keys(['name', 'age', 'hobby', 'jj'])
print(dict1.values()) #dict_values(['张三', 66, '篮球', 88])
print(dict1.items()) #dict_items([('name', '张三'), ('age', 66), ('hobby', '篮球'), ('jj', 88)])
# 五、其他
# 但凡是可变的数据类型,都有copy(),从实用性角度考虑,有可能改变的数据才需要备份。
# 字典同样可以使用copy(),copy.copy(),copy.deepcopy()。
# 字典同样遵循和列表一样的深浅拷贝的特征。
# 一般拷贝用copy.deepcopy()。
集合
- 概念
1、Python中的集合跟数学上的集合是一致的,不允许有重复元素,而且可以进行交集、并集、差集等运算。
2、set与dict类似,但是与dict的区别在于只是一组key的集合,不存储value
3、本质:无序且无重复元素的集合
4、表示:{},注意:如果直接使用{}则默认表示字典。
5、【面试题】:简述列表,元组,字典,集合和字符串的区别?
- 列表的本质:list,是一种有序的,可变的,可以存储重复元素的,可以存储不同类型数据的集合
- 元组的本质:tuple,是一种有序的,不可变 的,可以存储重复元素的,可以存储不同类型数据的集合
- 字典的本质:dict,是一种有序的【Python3.7之后】,可变的,key不可以重复,但是value可以重复,key只能是不可变的数据类型,vlue可以是任意的类型的 集合
- 集合的本质:set,是一种无序 的,可变的,不可以存储重复元素 的,可以存储不同类型的集合
- 字符串的本质:str,是一种有序的,不可变的,可以存储重复字符的集合
# 1.定义
# a.定义一个空集合
# {}默认表示字典
dict1 = {}
print(type(dict1)) #<class 'dict'>
set1 = set() #为了区分字典和集合
print(set1) #set()
# b.定义一个非空集合
set2 = {3,5,6}
print(set2,type(set2)) #{3, 5, 6} <class 'set'>
# c.去重
set3 = {3,3,3,3,4,5,6,6,6,6}
print(set3) #{3, 4, 5, 6}
# d.无序
set4 = {7,2,45,2,6,7,8,9,10}
print(set4) #{2, 6, 7, 8, 9, 10, 45}
# 练习:去重一个列表中的重复元素
list1 = [45,67,7,8,2,2,2]
list2 = list(set(list1))
print(list2) #[2, 67, 7, 8, 45]
# 2.运算(1、&;2、|;3、-;4、^;5、系统功能intersection();6、系统功能union;7、系统功能difference)【集合的交并补结果还是集合】
s1 = {1,2,3}
s2 = {3,4,5}
# 2.1符号
# a.交集
print(s1 & s2) # {3}
# b.并集
print(s1 | s2) # {1, 2, 3, 4, 5}
# c.差集
print(s1 - s2) # {1, 2}
# e.并集-交集【^运算对于集合来说就是去除交集之后,两个集合所有元素】
s1 = {1,2,3}
s2 = {3,4,5}
print(s1 ^ s2) # {1, 2, 4, 5}
print(s2 ^ s1) # {1, 2, 4, 5}
# 2.2系统功能
# a.交集
r1 = s1.intersection(s2) # {3}
print(r1)
# b.并集
r1 = s1.union(s2) # {1, 2, 3, 4, 5}
print(r1)
# c.差集
r1 = s1.difference(s2)
print(r1) # {1, 2}
# 集合和字典之间的联系:集合相当于存储了字典中的key
# 一、增(1、系统功能add;2、系统功能update)
# 1.add(x),x只能是不可变的数据类型,如果x是一个可迭代对象,则【整体加入】
s1 = {11,22,33}
print(s1)
s1.add(44)
print(s1)
s1.add("abc")
print(s1)
s1.add(True)
print(s1) #{33, True, 11, 44, 'abc', 22}
s1.add((55,66))
print(s1) #{33, True, (55, 66), 11, 44, 'abc', 22}
# s1.add([55,66]) # TypeError: unhashable type: 'list'
# s1.add({'a':10}) # TypeError: unhashable type: 'dict'
print("*" * 30)
# 2.update(x),x只能是可迭代对象(能遍历的容器),只会将可迭代对象中的元素加入【打碎加入】
# 可迭代对象:list,tuple,dict,set,set,range()等容器
s1 = {11,22,33}
print(s1)
# s1.update(44) # TypeError: 'int' object is not iterable可迭代对象
s1.update("abc")
print(s1) #{33, 11, 'b', 'a', 22, 'c'}
# s1.update(True) # TypeError: 'bool' object is not iterable
s1.update((55,66))
print(s1) #{33, 66, 11, 'b', 'a', 22, 55, 'c'}
s1.update([77,88])
print(s1) #{33, 66, 11, 77, 'b', 'a', 22, 55, 88, 'c'}
s1.update({'x':10,'y':20}) # 注意:如果x是字典,只能添加key
print(s1) #{33, 66, 'y', 11, 'x', 77, 'b', 'a', 22, 55, 88, 'c'}
# 二、删(1、系统功能remove();2、系统功能pop()集合无序,随机删除;3、系统功能discard();4、系统功能clear())
# 1.remove(x):x表示需要删除的元素 ******
s1 = {11,22,33,4,78,79}
print(s1)
s1.remove(33)
print(s1) #{4, 22, 11, 78, 79}
# s1.remove(100) # KeyError: 100
# 2.pop():因为集合是无序的,所以pop表示随机删除一个
s1 = {11,22,33,4,78,79}
print(s1)
s1.pop()
print(s1)
# 3.discard(x):和remove用法相同,如果被删除的元素不存在,remove会报错,但是discard不会报错 *****
#discard v. 扔掉,弃置;
s1 = {11,22,33,4,78,79}
print(s1) #{33, 4, 22, 11, 78, 79}
s1.discard(33)
print(s1) #{4, 22, 11, 78, 79}
s1.discard(100)
print(s1) #{4, 22, 11, 78, 79}
# 4.clear():清空
s1.clear()
print(s1) # set()
#三、改(无序没法索引,所以没法查!)
# 四、查
s1 = {11,22,33,4,78,79}
s2 = s1.copy()
print(len(s1)) #6
print(max(s1)) #79
print(min(s1)) #4
# int()/float()/bool()/list()/tuple()/dict()/set()