Python学习笔记(3-5):内置数据结构之字典
文章导读
- 课程难度:★☆☆☆☆
- 预计学习时间:40分钟
- 简介:本节主要讲解了Python内置数据结构中字典数据的基础知识及常用方法函数,包括:(1)字典的定义;(2)基于多种方式的访问;(3)字典的修改、合并与删除;(4)字典用于函数传参的使用方法及示例;
- 重点涉及的函数和内容:(1)定义字典时元素的“键”必须为不可变数据类型,且“键”不能重复;(2)利用“键”作为下标来访问“值”、利用get()方法获取指定“键”对应的“值”、利用.keys()和.values()方法来获取所有的“键”和“值”、利用in关键字判断字典是否含某个“键”;
(3)利用update()方法合并字典、del()和pop()删除字典元素;
一、字典的定义
字典是一个容器对象,其中的元素以“键值对”的形式存在,各元素的“键”和“值”用冒号分隔开以表示对应关系,元素间用逗号分隔开,所有的元素放在一对大括号中{}
。需要注意的是,字典中元素的“键”必须为不可变数据类型,如:整数、浮点数、复数、字符串、元组等,不可以是列表、集合或其他可变类型的数据,包括列表等可变类型的元组也不能作为字典的“键”。
data = dict(name='张三',age=30,sex = 'M')
print(data)
输出结果如下:
{'name': '张三', 'age': 30, 'sex': 'M'}
需要注意的是,字典中元素的“键”不可以重复,但“值”可以
二、字典的访问
1、利用“键”作为下标,访问“值”
data = dict(name='张三',age=30,sex = 'M')
print(data['name'])
输出结果如下:
张三
2 、利用get()方法
使用get()
方法可以获取指定“键”对应的“值”,示例如下:
data = dict(name='张三',age=30,sex = 'M')
print(data.get('age'))
print(data.get('address','不存在这个键')) # "键"不存在时,返回默认值
输出结果如下:
30
不存在这个键
3、利用.keys()和.values()方法
我们可以使用.keys()
和.values()
方法获取所有的“键”和“值”
data = dict(name='张三',age=30,sex = 'M')
print(data.keys()) #获取所有"键"
print(data.values()) #获取所有"值"
print(list(data.keys())) #把所有的"键"转换为列表
print(list(data.values())) #把所有的"值"转换为列表
输出结果如下:
dict_keys(['name', 'age', 'sex'])
dict_values(['张三', 30, 'M'])
['name', 'age', 'sex']
['张三', 30, 'M']
4、成员测试运算符 in
关键字in
这种方法只对键有用,对值没有用。示例如下:
data = dict(name='张三',age=30,sex = 'M')
print('name' in data)
print('address' in data) # address不是data的键
print(30 in data) # 30是data的值,不是键,所以返回False
输出结果如下:
True
False
False
三、字典的修改、合并与删除
1、字典的修改
对字典中元素进行修改,可以通过以指定”键“为下标访问"值"并对其进行修改,若”键“存在,则完成修改;若”键“不存在,则新添加了该元素。示例如下:
data = dict(name='张三',age=30,sex = 'M')
data['name']='李四' #修改值
print(data)
data['address']='BJ' #新添加一个元素
print(data)
输出结果如下:
{'name': '李四', 'age': 30, 'sex': 'M'}
{'name': '李四', 'age': 30, 'sex': 'M', 'address': 'BJ'}
2、字典的合并:update()
利用update()
函数,可以将字典a的元素全部添加到字典b中,若两个字典存在相同的"键",则以字典a中的”值“为准对字典b进行更新,语法形式为:b.update(a)
,具体示例如下:
a = {'name': '张三', 'age': 30, 'sex': 'M'}
b = {'name':'张三','age':20,'sex':'M','address':'BJ'}
print(b.update(a)) #该方法不返回值,只更改b的元素
b.update(a)
print(b)
输出结果如下:
None
{'name': '张三', 'age': 30, 'sex': 'M', 'address': 'BJ'}
3、字典的删除:del()、pop()
二者的调用方式是不同的,但除了pop()
会返回待删除的值之外,从结果上没有任何不同。
(1).del()
:del()
是一个保留字,直接利用del()
接上想要删除的字典元素即可。但是通过del()
删除一个键时如果这个键不存在,则会报错:
data = dict(name='张三',age=30,sex = 'M')
del data['name'] #第一次删除
print(data)
del data['name'] #第二次删除,报错,没有这个键不能删除
print(data)
输出结果如下:
{'age': 30, 'sex': 'M'}
#报错 【KeyError: 'name'】
(2).pop()
:这是字典的一个成员方法,删除字典的值只需要传递待删除的键即可。但是,如果一个字典中没有这个键,会报错。同时,.pop()
不接受一次性删除多个键。我们用如下的例子观察程序的执行效果:
data = dict(name='张三',age=30,sex = 'M')
data.pop('sex') #第一次删除
print(data)
data.pop('sex') #报错1,没有这个键不能删除
data.pop(['name','sex']) #报错2,不接受列表作为删除键的参数
data.pop(('name','sex')) #报错3,字典中没有('name','sex')这个键
输出结果如下:
'M'
{'name': '张三', 'age': 30}
# 报错1【KeyError: 'sex'】
# 报错2【unhashable type: 'list'】
# 报错3【KeyError: ('name','sex')】
这里面我们可以发现,del()
和pop()
都不能通过传一个列表或元组来达到批量删除键,而只能写一个循环,一个一个删。
四、补充:用于函数传参的字典
因为键值对不能切片访问、不能批量删除、不能通过下标访问,因此它的应用场景并不太多地面向具体的数据分析任务,在此举一例它的价值,在参数传递上。传递函数参数时可以一次传具有许多参数的字典,这就能保证程序的同名参数不会相互覆盖即“打架”,也令程序各参数使用意义明确。
相对技巧性更强的的传递targs
,kwargs
参数、即可变的位置参数和关键字参数的使用方式也在这里一并提及:
我们这里新定义一个函数,这个函数很简单,输出所有的值,注意参数的写法:
def test(arg0, *targs, **kwargs):
print(arg0)
print("*****")
for var in targs:
print(var)
print("*****")
for var in kwargs:
print(var, kwargs[var])
在这里,我们发现有三个参数,第一个是位置参数arg0
,第二个是*targs
,代表一组位置参数,用列表或者元组括起来,它表示若干(未知)个位置参数。最后一个是**kwargs
,代表一组关键字参数,用字典来定义,它表示若干(未知)个关键字参数。
接下来我们分别定义这两组位置参数和关键字参数:
arg0 = 100
targs = ('alpha', 'beta', 'gamma')
kwargs = {
'a': 12,
'b': 20,
'calfun': 'sum'
}
调用这个函数的时候,对于传入的这组位置参数和这组关键字参数的变量,我们分别用 *
和 **
指示。在函数里,这三类参数的定义顺序和传入顺序不能变。不过arg0
可以不定义,targs
会解包数个值传给前面的位置参数。
test(arg0, *targs, **kwargs)
print('~~~~~ no arg0 ~~~~~')
test(*targs, **kwargs)
输出结果如下:
100
*****
alpha
beta
gamma
*****
a 12
b 20
calfun sum
~~~~~ no arg0 ~~~~~
alpha
*****
beta
gamma
*****
a 12
b 20
calfun sum
那么做了这样许多铺垫,我们对这个字典应用在实际场景的方式举两个例子:
例1:我们将定义一个**kwargs
,里面是全部函数所需的参数,参数名称用字符串表示即可,传参时字典用 **
指示。这里就只说传入关键字参数的事情,对于位置参数的传入,其用 *
指示,用法是相似的。此时的函数参数仍然可以带默认值,如果字典里没有定义某个参数,就会利用上默认值。
def fun(a, b = 10, calfun = 'product'):
if calfun == 'sum':
return a + b
elif calfun == 'product':
return a * b
else:
return 'Please Choose function \'sum\' or \'product\''
kwargs = {
'a': 12,
'b': 20,
'calfun': 'sum'
}
fun(**kwargs)
输出结果如下:
32
例2:我们直接定义一个 **kwargs
的参数,直接把这个字典传进去,在函数里手动提取这些参数。
def fun(**kwargs):
a = kwargs['a'] if 'a' in kwargs else 0 # if-else中的三元表达式
b = kwargs['b'] if 'b' in kwargs else 0
calfun = kwargs['calfun'] if 'calfun' in kwargs else 'sum'
if calfun == 'sum':
return a + b
elif calfun == 'product':
return a * b
else:
return 'Please Choose function \'sum\' or \'product\''
kwargs = {
'a': 12,
'b': 20,
'calfun': 'sum'
}
fun(**kwargs)
输出结果如下:
32
我们比较刚刚这种调用和如下我们的一般写法:
def fun(a, b = 10, calfun = 'sum'):
if calfun == 'sum':
return a + b
elif calfun == 'product':
return a * b
else:
return 'Please Choose function \'sum\' or \'product\''
a = 12
b = 20
calfun = 'sum'
fun(a,b, calfun = calfun)
输出结果如下:
32
在这样简单的函数里我们看不出来什么显著的差别,几种方式都能做到函数调用的形式清晰,甚至字典还要通过更麻烦的方式实现参数的初始化。
但是它的好处在于,一是我们可以传入任意数量的信息,对于多出来的键值对,我们可以忽略或做其他处理,而不是报错,这样甚至可以做到一套字典作为参数传递给各种函数。二是如果我们对每个函数传入某个特定字典,就不用设置许多全局参数并仔细设计名称,也无需经常考虑各种参数可能的覆盖和被其他函数无意修改的情况。
对于缺乏Python基础的同仁,可以通过免费专栏🔥《Python学习笔记(基础)》从零开始学习Python
结语
请始终相信“Done is better than perfect”
,不要过分追求完美,即刻行动就是最好的开始, 一个模块一个模块地积累和练习,必将有所收获。
还有其他的问题欢迎在评论区留言📝!
[版权申明] 非商业目的注明出处可自由转载,转载请标明出处!!!
博客:butterfly_701c