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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值