首页 > 编程语言 >Python 1-18 字典

Python 1-18 字典

时间:2023-05-22 11:04:48浏览次数:34  
标签:Name Python 18 dic dict key print 字典


Python 1-18 字典

Python 的字典数据类型采用键值对 (key:value) 的形式,根据 key 的值计算 value 的地址,具有非常快的查取和插入速度。

例如,用 list 实现成绩单:

# 给定一个名字,要查找对应的成绩,就先要在 names 中找到对应的位置,再从 scores 取出对应的成绩,list 越长,耗时越长。
names = ['张三', '李四', '王五']
scores = [95, 75, 85]
name = '李四' 
try:   
    print(f'{name}:{scores[names.index(name)]}')
except Exception as e:
    print(e)

如果用 dict 实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,查找速度很快。

>>> d = {'张三': 95, '李四': 75, '王五': 85}
>>> d['李四']
75

为什么 dict 查找速度比 list 快?因为 dict 的实现原理和查新华字典是一样。

在 list 中查找元素的方法是从头往后一个一个查,list 越大,查找越慢。
在 dict 中可以直接计算出 “李四” 对应的存放成绩 95 的内存地址,直接取出来,所以速度非常快。

list:查找和插入的时间随着元素的增加而增加;占用空间小。
dict:查找和插入的速度极快,不会随着 key 的增加而变慢;需要占用大量的内存。

dict 是用空间来换取时间的一种方法。

注意:从Python3.6开始,字典是有序的!它将保持元素插入时的先后顺序!

字典格式:

d = {key1 : value1, key2 : value2 }

1、创建字典

# class dict(**kwarg)
# class dict(mapping, **kwarg)
# class dict(iterable, **kwarg)
>>>dict()                        # 创建空字典
{}
>>> type(dict) # <class 'dict'>
>>> dict(a=1, b=2, t=3)     # 传入关键字
{'a': 1, 'b': 2, 't': 3}
>>> dict(zip(['one', 'two', 'three'], [1, 2, 3]))   # 映射函数方式来构造字典
{'one': 1, 'two': 2, 'three': 3} 
>>> dict([('one', 1), ('two', 2), ('three', 3)])    # 可迭代对象方式来构造字典
{'one': 1, 'two': 2, 'three': 3}

2、访问字典

虽然现在的字典在访问时有序了,但字典依然是集合类型,不是序列类型,因此没有索引下标的概念,更没有切片的说法。
但与 list 类似的地方是,字典采用把相应的键放入方括号内获取对应值的方式取值。

dic = {'Name': 'Python', 'Age': 7, 'Class': 'First'}
print("dic['Name']: ", dic['Name'])

如果用字典里没有的键访问数据,会输出错误如下:

print ("dict['Alice']: ", dic['Alice']) # KeyError: 'Alice'

要避免 key 不存在的错误,有两种办法,一是通过 in 判断 key 是否存在:

'Thomas' in dic # False

二是通过 dict 提供的 get() 方法,如果 key 不存在,可以返回 None,或者自己指定的 value:

dic.get('Thomas',default=None)
dic.get('Thomas', -1) # -1

注意:返回 None 的时候 Python 的交互环境不显示结果。

3、增加和修改

由于一个 key 只能对应一个值,所以,多次对一个 key 赋值,后面的值会把前面的值覆盖掉。

dic = {'Name': 'Python', 'Age': 7, 'Class': 'First'}
dic['Age'] = 8 # 更新 Age
dic['School'] = "Python" # 添加信息
print (dic)

4、删除字典元素、清空字典和删除字典

使用 del 关键字删除字典元素或者字典本身,使用字典的 clear() 方法清空字典。

dic = {'Name': 'Python', 'Age': 7, 'Class': 'First'}
del dic['Name'] # 删除键 'Name'
dic.clear() # 清空字典
del dic # 删除字典
print ("dic['Age']: ", dic['Age'])

但这会引发一个异常,因为用执行 del 操作后字典不再存在:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print ("dic['Age']: ", dic['Age'])
TypeError: 'type' object is not subscriptable

要删除一个 key,用 pop(key) 方法,对应的 value 也会从 dict 中删除:

>>> dic = {'Name': 'Python', 'Age': 7, 'Class': 'First'}
>>> dic.pop('Age')
7

5、字典键的特性

键必须是唯一的、不可变的,键可以是字符串,数字或元组,值可以取任何数据类型。

1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住:

dic = {'Name': 'Python', 'Age': 7, 'Name': '小菜鸟'}
print ("dic['Name']: ", dic['Name'])

2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行:

dic = {['Name']: 'Python', 'Age': 7}
print ("dic['Name']: ", dic['Name']) # TypeError: unhashable type: 'list'

6、字典内置函数 & 方法

len(dict) # 计算字典元素个数,即键的总数。
str(dict) # 输出字典,以可打印的字符串表示。

>>> dict = {'Name': 'Python', 'Age': 7, 'Class': 'First'}
>>> str(dict) # "{'Name': 'Python', 'Class': 'First', 'Age': 7}"

Python字典包含了以下内置方法:

dict.get(key, default=None) 	# 返回指定键的值,如果键不在字典中返回 default 值
dict.setdefault(key, default=None) # 和 get() 类似, 但如果键不存在于字典中,将会添加键并将值设为 default	

dict.pop(key[,default]) # 删除字典给定键及其所对应的值,返回被删除键的值。如果键不存在,返回 default 值。
dict.popitem() # 返回(键,值)元组并删除字典中的最后一对键和值。
dict.clear() 	# 删除字典内所有元素

dict.copy() 	# 返回一个字典的浅复制
dict.fromkeys(seq[, value]) # 创建一个新字典,以序列 seq 中元素做字典的键,value为字典所有键对应的初始值。
dict.update(dict2) # 把字典 dict2 的键/值对更新到 dict 里	

dict.items() # 返回一个迭代器,返回可遍历的(键, 值) 元组列表
dict.keys() # 返回一个迭代器,返回可遍历的键列表
dict.values() # 返回一个迭代器,返回可遍历的值列表

7、遍历字典

从 Python3.6 开始遍历字典获得的键值对是有序的。

dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}

# 1  直接遍历字典获取键,根据键取值
for key in dic:
    print(key, dic[key])  
      
# 2 利用keys方法获取键
for key in dic.keys():
    print(key, dic[key])
    
# 3  利用items方法获取键值,速度很慢,少用!
for key,value in dic.items():
    print(key,value)
    
#4  利用values方法获取值,但无法获取对应的键。
for value in dic.values():
    print(value)

8、综合展示

看下面的例子,其中有一些是错误做法展示:

>>> dic = {}
>>> for i in 'adilwste':
...     dic[i] = ord(i)
...
>>> dic
{'a': 97, 'd': 100, 'i': 105, 'l': 108, 'w': 119, 's': 115, 't': 116, 'e': 101}
>>> for i in dic:
...     print(i,dic[i])
...
a 97
d 100
i 105
l 108
w 119
s 115
t 116
e 101
>>> dic[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 0
>>> dic.pop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pop expected at least 1 argument, got 0
>>> dic.popitem()
('e', 101)
>>> dic
{'a': 97, 'd': 100, 'i': 105, 'l': 108, 'w': 119, 's': 115, 't': 116}
>>> dic.popitem('d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: popitem() takes no arguments (1 given)
>>> a = dic.popitem()
>>> a
('t', 116)

Python 直接赋值、浅拷贝和深度拷贝

直接赋值:就是对象的引用(别名)。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。即内容子对象引用相同。
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

字典浅拷贝:

>>> a = {1: [1,2]}
>>> b = a.copy()
>>> a, b
({1: [1, 2]}, {1: [1, 2]})
>>> a[1].append(3)
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})

深度拷贝需要引入 copy 模块:

>>> import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3]})

解析

1、b = a: 赋值引用,a 和 b 都指向同一个对象。
2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
3、b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。

以下实例是使用 copy 模块的 copy.copy( 浅拷贝 )和(copy.deepcopy ):

import copy

a = [1, 2, ['a', 'b']] #原始对象
b = a #赋值,传对象的引用
c = copy.copy(a) #对象拷贝,浅拷贝
d = copy.deepcopy(a) #对象拷贝,深拷贝
a.append(3) #修改对象a
a[2].append('c') #修改对象a中的['a', 'b']数组对象
print( 'a = ', a )
print( 'b = ', b )
print( 'c = ', c )
print( 'd = ', d )

以上实例执行输出结果为:

a =  [1, 2, ['a', 'b', 'c'], 3]
b =  [1, 2, ['a', 'b', 'c'], 3]
c =  [1, 2, ['a', 'b', 'c']]
d =  [1, 2, ['a', 'b']]


标签:Name,Python,18,dic,dict,key,print,字典
From: https://blog.51cto.com/u_1439909/6321625

相关文章

  • Python 1-17 元组
    Python1-17元组classtuple([iterable])tuple是一个不可变的序列类型。>>>s='abc'>>>l=[1,2]>>>t=1,2>>>d=dict(a=1,b=2)>>>set={'a','b'}1、元组创建>>>tup=()#创建空元组>>......
  • Python 2-02 命名空间和作用域
    命名空间和作用域一、命名空间命名空间(Namespace)是从名称到对象的映射,一般用Python字典来实现。为了解决项目中名字冲突的问题引入了命名空间的概念,命名空间可以嵌套。1、命名空间分类:内置名称(built-innames),Python语言内置的名称,比如函数名abs、char和异常名称Exception......
  • Python 2-01 函数
    一、函数定义def函数名(参数列表):函数体判断一个数是不是素数?#方法一:for循环判断素数num=int(input('请输入一个正整数:'))foriinrange(2,int(num**0.5)+1):ifnotnum%i:print(f'{num}不是素数')breakelse: print(f'{num}是素数')......
  • Python 2-06 闭包
    闭包Closures嵌套函数(nestedfunction),内函数引用了外函数的临时变量,并且外函数返回内函数的引用,这样就构成了一个闭包。defouter():x,y,z=10,'abc',[1,2]definner():print(x,y)returninnerf=outer()print(f.__closure__)#celltuple......
  • Python 1-24 练习五 综合练习
    1、无重复字符的最长子串给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。#substr向右扩展一个元素,如果该元素已经在substr中,则需要将其及其前面的元素去掉。#可通过substr.index(c)定位元素或substr.split(c)[1]分割成子串#发现有重复字符时,可......
  • Python 2-05 高阶函数
    一、函数式编程函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。而函数式编程(请注意多了一个“式”字)——FunctionalProgrammi......
  • Python 3-11 异常处理
    异常处理一、错误和异常1、句法错误句法错误又称解析错误:>>>whileTrueprint('Helloworld')File"<stdin>",line1whileTrueprint('Helloworld')^SyntaxError:invalidsyntax解析器会复现出现句法错误的代码行,并用小“箭头”指向行里检测到的第一......
  • Python 05 Selenium 等待
    等待WebDriver通常可以说有一个阻塞API。因为它是一个指示浏览器做什么的进程外库,而且web平台本质上是异步的,所以WebDriver不跟踪DOM的实时活动状态。大多数由于使用Selenium和WebDriver而产生的间歇性问题都与浏览器和用户指令之间的竞争条件有关。例如,用户指示浏览......
  • Python 1-11 练习一
    Python1-11练习一一、已知字符串s=“aAsmr3idd4bgs7Dlsf9eAF”,要求如下1、请将s字符串的大写改为小写,小写改为大写。#使用字符串的内置方法a.swapcase():s='aAsmr3idd4bgs7Dlsf9eAF't=s.swapcase()print(t)2、请将s字符串的数字取出,并输出成一个新的字符串。s=......
  • Python 1-10 字符串操作
    Python1-10字符串操作1、字符串拼接>>>s='hello'*2>>>s='hello'+'world'>>>s='hello''world'>>>......