6月1号,Python元组、字典、集合

6月1号,Python元组、字典、集合_第1张图片

1 元组的介绍

  • 一般当数据不改变时,用元组,其余情况用列表。

1.1 元组的创建

  • 用()
  • 对比——列表的创建:[]

输入:

tup=()
print(tup,type(tup))

得到:

() <class 'tuple'>

添加元素如下:

tup=(1,2,3,4,5)
print(tup,type(tup))

得到:

(1, 2, 3, 4, 5) <class 'tuple'>
  • 元组也可以通过索引值来进行取值
tup=(1,2,3,4,5)
print(tup[3])

得到:

4
  • 元组不能通过索引值来赋值
tup=(1,2,3,4,5)
tup[3]=44
print(tup)

报错:

TypeError: 'tuple' object does not support item assignment

元组是不可变序列,或称不可变对象

tup=10
print(tup,type(tup))

得到:

10 <class 'int'>

此时元组中的数为整型,我们稍加改变:

tup=10,
print(tup,type(tup))

得到:

(10,) <class 'tuple'>

此时就变成了一个元祖。又例如:

tup=1,2,3,4,5
print(tup,type(tup))

输出:

(1, 2, 3, 4, 5) <class 'tuple'>

不加括号,它也是一个元组。因此我们总结如下:

如果元组不是空的,那么它里面至少得有一个逗号

1.2 元组的解包

tup=10,20,30,40
a,b,c,d=tup
print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)

得到:

a= 10
b= 20
c= 30
d= 40

感觉似曾相识?回顾这个例子:

a=6
b=8
b,a=a,b
print(a,b)

得到:

8 6

如果我们用两个值解剖四个元素,会出现什么情况呢?

tup=10,20,30,40
a,b=tup
print('a=',a)
print('b=',b)

报错:

ValueError: too many values to unpack (expected 2)

理论上,变量必须和元素一一对应,若不满足,需要加*(详见下面的内容)。

该如何调整呢?理论上我们应该再添加两个,但是如果这里缺的值有10000个,我们总不能添加10000个变量吧,因此,我们使用:

tup=10,20,30,40
a,b,*c=tup
print('a=',a)
print('b=',b)

此时:

a= 10
b= 20

我们可以看看此时c是什么效果:

tup=10,20,30,40
a,b,*c=tup
print('a=',a)
print('b=',b)
print('c=',c)

得到:

a= 10
b= 20
c= [30, 40]

说明:剩下的元素以列表的形式全部储存在c中,不用考虑变量有多少个。

那么,另一个问题来了,如果想存储中间的元素呢?

tup=10,20,30,40
a,*b,c=tup
print('a=',a)
print('b=',b)
print('c=',c)

得到:

a= 10
b= [20, 30]
c= 40

把第一个给了a,最后一个给了c,剩下的中间部分全部给了b

同理:

tup=10,20,30,40
*a,b,c=tup
print('a=',a)
print('b=',b)
print('c=',c)

结果可想而知:

a= [10, 20]
b= 30
c= 40

这个功能在列表里是否适用呢?

a,b,*c=[1,2,3,4,5,6,7]
print('a=',a)
print('b=',b)
print('c=',c)

得到:

a= 1
b= 2
c= [3, 4, 5, 6, 7]

也是可以的。字符串呢?

a,b,*c='Python'
print('a=',a)
print('b=',b)
print('c=',c)

得到:

a= P
b= y
c= ['t', 'h', 'o', 'n']

只要是序列,都可以,都是通用的。但若有两个*号:

a,*b,*c='Python'
print('a=',a)
print('b=',b)
print('c=',c)

报错:

SyntaxError: two starred expressions in assignment

小结:不能同时出现两个及两个以上的*

2 字典的创建

  • 字典属于一种新的数据结构,我们称之为‘映射’(mapping)
  • 作用:用来存储对象的容器
  • 字典与列表的区别?列表存储数据的性能特别好,但查询数据性能比较差;字典正好与之相反。

例如,在列表中存了10000个数据,想在其中找到“钢铁侠”,知道索引还好办,不知道就比较麻烦了。

平时的字典查询方法:偏旁部首
Python中的字典:通过唯一名字(页码),快速找到。

  • 字典中每一个元素都有唯一名字,通过这个唯一的名字快速找到指定的元素
  • 唯一的名字:key
  • 通过key来查询值,值称之为value,键值对(key-value),字典中可以有多个键值对,一项称之为Item
d={}
print(d,type(d))
{} <class 'dict'>

这是个空字典,可以往里面添加元素。语法如下:

{key:value,key:value...}

例如:

d={'name':'葫芦娃','age':'20','sex':'男'}
print(d,type(d))

得到:

{'name': '葫芦娃', 'age': '20', 'sex': '男'} <class 'dict'>

key和value分别可以是哪些值呢?归纳如下:

字典中的值value可以是任意对象,可变不可变均ok

字典的key可以是任意不可变对象(int str bool tuple…)

那key可以重复吗?

d={'name':'葫芦娃','age':20,'sex':'男','name':'钢铁侠'}
print(d,type(d))

得到:

{'name': '钢铁侠', 'age': 20, 'sex': '男'} <class 'dict'>

因此:

字典中的key不能重复,若出现重复,后面的会替代前面的。

若键值较多时,也可以下面的这种书写方式:

headers={
    'name':'葫芦娃',
    'age':20
}
  • 根据键来获取值
d={'name':'葫芦娃','age':20,'sex':'男','name':'钢铁侠'}
print(d['name'],d['age'],d['sex'])

得到:

钢铁侠 20

3 字典的使用

  • 参考官网文档

  • 可以使用dict()函数来创建字典

d=dict(name='葫芦娃',age=18,sex='男')
print(d,type(d))

得到:

{'name': '葫芦娃', 'age': 18, 'sex': '男'} <class 'dict'>

表示向函数中传递3个参数。

或者:

d=dict([('name','葫芦娃'),('age',18)])
print(d,type(d))

得到:

{'name': '葫芦娃', 'age': 18} <class 'dict'>

事实上,这是一个双值子序列

何为双值子序列呢?

  • 双值序列:序列中有2个值,如 [3,4] ‘mn’ ('w',8)

  • 子序列:序列中的元素也是序列,比如列表中套了一个列表。

  • 双值子序列:既是双值序列也是子序列,如[(3,4),(5,6)]

  • len()函数:获取字典中键值对的个数

d=dict(name='葫芦娃',age=18,sex='男')
print(len(d))

得到:

3
  • in:检查字典中是否包含指定的
    not in:检查字典中是否不包含指定的
d=dict(name='葫芦娃',age=18,sex='男')
print('name'in d)
print('葫芦娃'in d)

得到:

True
False

我们再输入:

d=dict(name='葫芦娃',age=18,sex='男')
print(d['age'])

得到:

18

但如果这么写:

d=dict(name='葫芦娃',age=18,sex='男')
print(d[age])

将会报错:

NameError: name 'age' is not defined

因此,

dict[key]中,key一定要加引号'',否则会当成变量来处理。

但如果这么写,把key赋值:

d=dict(name='葫芦娃',age=18,sex='男')
n='name'
print(d[n])

输出:

葫芦娃

此时就不用加引号''

当我们输入一个不存在的键:

print(d['n'])

就会报错,程序会终止

KeyError: 'n'

此时有一种更柔和的方式:

print(d.get('n'))

得到:

None
  • get()get(key[,default])。default表示非必须,该方法根据字典中的key来获取值,如果你的key不存在,返回None。
d=dict(name='葫芦娃',age=18,sex='男')
print(d.get('name'))

得到:

葫芦娃

也可以指定第二个参数,当key值不存在时,会返回默认值。

d=dict(name='葫芦娃',age=18,sex='男')
print(d.get('n','key值不存在'))

得到:

key值不存在
  • 修改字典

输入:

d=dict(name='葫芦娃',age=18,sex='男')
d['name']='钢铁侠'
print(d)

得到:

{'name': '钢铁侠', 'age': 18, 'sex': '男'}

字典中的k-v被修改。那如果原本就不存在的key值呢?

d=dict(name='葫芦娃',age=18,sex='男')
d['name']='钢铁侠'
d['phone']=['131313']
print(d)

得到:

{'name': '钢铁侠', 'age': 18, 'sex': '男', 'phone': ['131313']}

相当于向字典中添加key-value。

  • d.setdefault(key,[,default]):可以向字典中添加k-v

输入:

d=dict(name='葫芦娃',age=18,sex='男')
d.setdefault('name','钢铁侠')
print(d)

结果不变:

{'name': '葫芦娃', 'age': 18, 'sex': '男'}

这是为什么呢?

原因:在使用d.setdefault(key,[,default])时,如果key已存在在字典当中,则返回key的值,不会对字典做任何操作;如果key不存在,则向字典中添加这个key,并设置value。

d=dict(name='葫芦娃',age=18,sex='男')
d.setdefault('name','钢铁侠')
d.setdefault('phone','钢铁侠')
print(d)

得到:

{'name': '葫芦娃', 'age': 18, 'sex': '男', 'phone': '钢铁侠'}
  • update():将其它字典的k-v添加到当前字典中

输入:

d1={'a':1,'b':2,'c':3}
d2={'d':4,'e':5,'f':6}
d1.update(d2)
print(d1)

得到:

{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}

d2字典中的k-v添加至了d1字典中,那么假如d1d2中有重复的key:

d1={'a':1,'b':2,'c':3}
d2={'d':4,'e':5,'f':6,'a':7}
d1.update(d2)
print(d1)

得到:

{'a': 7, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}

如果有重复的key,后面的value会替换前面的value。

  • del:删除字典中的k-v

注意语法:

d1={'a':1,'b':2,'c':3}
del d1['a']
del d1['b']
print(d1)

得到:

{'c': 3}
  • popitem():随机删除字典中的一个k-v,一般都会删除最后一个。
d1={'a':1,'b':2,'c':3}
d1.popitem()
d1.popitem()
print(d1)

得到:

{'a': 1}

注意,popitem()是有返回值的,删除之后会将删除后的元素以元组形式返回。

d1={'a':1,'b':2,'c':3}
r=d1.popitem()
print(r)

得到:

('c', 3)
  • pop('key'[,default]):根据key来删除字典中的k-v
d1={'a':1,'b':2,'c':3}
r=d1.pop('b')
print(r)
print(d1)

得到:

2
{'a': 1, 'c': 3}

会将删除的value返回。

若删除了一个不存在的值:

d1={'a':1,'b':2,'c':3}
r=d1.pop('w','这个key值不存在')
print(r)
print(d1)

得到:

这个key值不存在
{'a': 1, 'b': 2, 'c': 3}

4 浅复制

  • 字面理解:复制得不深,浅浅地

一个小问题:下面这个算复制吗?

d1={'a':1,'b':2,'c':3}
d2=d1
print('d1=',d1)
print('d2=',d2)

答案:不算,d2d1指向的是同一个对象。拿我们小时候“复制”别人的作业为例,复制完成之后,你们二者的作业压根没什么关系,可能你改了它没改,它改了你没改。

  • 复制以后的对象与原对象是独立的,修改其中一个不会影响另一个。

id()可以看出,下面这个就是复制了。

d1={'a':1,'b':2,'c':3}
d2=d1.copy()
d1['b']=5000
print('d1=',d1,id(d1))
print('d2=',d2,id(d2))

得到不同的id值:

d1= {'a': 1, 'b': 5000, 'c': 3} 2715805364088
d2= {'a': 1, 'b': 2, 'c': 3} 2715805364160

另一个例子,也是复制:

d1={'a': {'name':'葫芦娃','age':20},'b':2,'c':3}
d2=d1.copy()
print('d1=',d1,id(d1))
print('d2=',d2,id(d2))

得到不同的id值:

d1= {'a': {'name': '葫芦娃', 'age': 20}, 'b': 2, 'c': 3} 1459300806592
d2= {'a': {'name': '葫芦娃', 'age': 20}, 'b': 2, 'c': 3} 1459300856168

下面,到底什么是“浅复制”呢?接着上一个例子:
d1={‘a’: {‘name’:‘葫芦娃’,‘age’:20},‘b’:2,‘c’:3}
d2=d1.copy()
d2[‘a’][‘name’]=‘黑猫警长’
print(‘d1=’,d1,id(d1))
print(‘d2=’,d2,id(d2))

结果:

d1= {'a': {'name': '黑猫警长', 'age': 20}, 'b': 2, 'c': 3} 2009964294080
d2= {'a': {'name': '黑猫警长', 'age': 20}, 'b': 2, 'c': 3} 2009964343656

d2变化了没问题,可为什么d1也会变化呢?不是说修改一个值不会影响另一个值吗?此即浅复制

浅复制仅仅只会复制字典本身,如果字典中还有个字典,是不会被复制的,因此此时内层并不独立,其中一个改动另一个就随之变化了。

这个值也可以是一个可变对象,这个可变对象也不会被复制。

5 遍历字典

  • keys():返回字典所有的key

例如:

d1={'a': {'name':'葫芦娃','age':20},'b':2,'c':3}
print(d1.keys())

得到key值:

dict_keys(['a', 'b', 'c'])

有了key,我们可以相应的找到value:

d1={'a': {'name':'葫芦娃','age':20},'b':2,'c':3}
for k in d1.keys():
    print(d1[k])

得到:

{'name': '葫芦娃', 'age': 20}
2
3
  • values():返回一个序列,序列中保存有字典的值

遍历如下:

d1={'a': {'name':'葫芦娃','age':20},'b':2,'c':3}
for v in d1.values():
    print(v)

得到:

{'name': '葫芦娃', 'age': 20}
2
3
  • items():返回字典所有的项,k-v双值序列

遍历如下:

d1={'a': {'name':'葫芦娃','age':20},'b':2,'c':3}
for k,v in d1.items():
    print(k,'=',v)

得到:

a = {'name': '葫芦娃', 'age': 20}
b = 2
c = 3

6 集合

  • 与列表非常相似,不同点如下:

1)集合只能存储不可变对象
2)集合中存储的对象是无序的
3)集合不能出现重复元素,集合中的元素是唯一的

6.1 集合的创建

回顾:

  • 列表创建:[]
  • 元组创建:()
  • 字典创建:{}

那么集合呢?

s={1,2,3,4}
print(s,type(s))

得到:

{1, 2, 3, 4} <class 'set'>

这就是集合创建,那不和字典是一样的嘛?!
注意,若用花括号{}创建空的内容:

s={}
print(s,type(s))

得到的就是字典:

{} <class 'dict'>

若添加元素,就是一个集合。这一块要区分。

集合不是说无序嘛,我们这样看:

s={6,2,4,1}
print(s,type(s))

得到:

{1, 2, 4, 6} <class 'set'>

因此,元素的插入顺序和最终输出结果不一样。

所谓无序,就是数据保存的顺序和插入顺序不一样。

  • set()
s=set()
print(s,type(s))

这是一个集合类型:

set() <class 'set'>

添加元素:

s=set(1,2,3)
print(s,type(s))

结果这是不行的:

TypeError: set expected at most 1 arguments, got 3

修改如下,以列表形式添加:

s=set([1,2,3,4,5])
print(s,type(s))

因此,将列表转化为集合,这是可以的:

{1, 2, 3} <class 'set'>

通过set()将字典转化为集合:

s= set({'a':1,'b':2,'c':3})
print(s,type(s))

得到:

{'a', 'b', 'c'} <class 'set'>

也是可以的,但只会包含key值。

在另一个例子中,我们看看在集合中能否通过索引来找到值,当我们输入:

s={'a','b',1,2,3}
print(s[0])
print(s,type(s))

显示报错:

TypeError: 'set' object does not support indexing

原因在于集合中的元素是无序的,系统无法得知‘0’对应谁,那在集合中该如何查找呢?

可以做一个类型转化:

s={'a','b',1,2,3}
print(list(s)[0])

得到:

1

6.2 集合的使用

你可能感兴趣的:(6月1号,Python元组、字典、集合)