乐趣区

关于人工智能:Python中的字典

作者 |Ankit Gupta
编译 |VK
起源 |Towards Datas Science

在这篇文章中,我将探讨字典。这是“Python 中的数据结构”系列的第二篇文章。本系列的第一局部是对于列表的。

字典是 Python 中应用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着程序不被保留。键是不可变的。

与列表一样,字典的值能够保留异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数组,甚至嵌套字典。

本文将为你提供一个清晰的了解,并使你可能熟练地应用 Python 字典。

本文包含以下主题:

  • 创立字典并增加元素
  • 拜访字典元素
  • 删除字典元素
  • 增加 / 插入新元素
  • 合并 / 连贯字典
  • 批改字典
  • 字典排序
  • 字典生成式
  • 创立字典的其余办法
  • 复制字典
  • 重命名现有键
  • 嵌套字典
  • 查看字典中是否存在键

1 创立字典并增加元素

像列表是用方括号 ([]) 初始化的,字典是用花括号 ({}) 初始化的。当然,空字典的长度是零。

dic_a = {} # 空字典

type(dic_a)
>>> dict

len(dic_a)
>>> 0

字典有两个特色:键和值。每个键都有相应的值。键和值都能够是 string、float、integer、NaN 等类型。向字典中增加元素意味着增加键值对。字典由一个或多个键值对组成。

让咱们在空字典里减少一些元素。上面是一种办法。这里,“A”是键,“Apple”是它的值。你能够增加任意多个元素。

# 增加第一个元素
dic_a['A'] = 'Apple'

print (dic_a)
>>> {'A': 'Apple'}

# 增加第二个元素
dic_a['B'] = 'Ball'

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball'}

留神:Python 辨别大小写,“A”和“a”充当两个不同的键。

dic_a['a'] = 'apple'

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'a': 'apple'}
一次初始化字典

如果你发现下面一个接一个增加元素的办法很烦人,那么你也能够通过指定所有键值对立刻初始化字典。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
异构字典

到目前为止,你的字典中有字符串作为键和值。字典也能够存储混合类型的数据。上面是一个无效的 Python 字典。

dic_b = {1: 'Ace', 'B': 123, np.nan: 99.9, 'D': np.nan, 'E': np.inf}

然而你应该为键应用有意义的名称,因为它们示意字典的索引。尤其要防止应用 float 和 np.nan 作为键。

2 拜访字典元素

创立了字典之后,让咱们看看如何拜访它们的元素。

拜访键和值

你能够应用函数 dict.keys()和 dict.values()别离拜访键和值。还能够应用 items()函数拜访元组模式的键和值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a.keys()
>>> dict_keys(['A', 'B', 'C'])

dic_a.values()
>>> dict_values(['Apple', 'Ball', 'Cat'])

dic_a.items()
>>> dict_items([('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')])

或者,也能够应用“for”循环一次拜访 / 打印一个。

# 打印键
for key in dic_a.keys():
    print (key, end=' ')
>>> A B C

#############################

# 打印值
for key in dic_a.values():
    print (key, end=' ')
>>> Apple Ball Cat

你能够防止两个“for”循环,并应用 items()拜访键和值。“for”循环将遍历 items()返回的键值对。这里,键和值是任意变量名。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

for key, value in dic_a.items():
    print (key, value)
>>> A Apple
    B Ball
    C Cat
拜访单个元素

无奈应用数字索引拜访字典项。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a[0]
>>> ----> 1 dic_a[0]
    KeyError: 0

你须要应用键从字典中拜访相应的值。

# 获取 "Apple" 的值
dic_a['A']
>>> 'Apple'

# 获取 "Cat" 的值
dic_a['C']
>>> 'Cat'

如果字典中不存在键,则会呈现谬误。

dic_a['Z']

>>> KeyError Traceback (most recent call last)
----> 1 dic_a['Z']

KeyError: 'Z'

如果心愿在不存在键的状况下防止此类键谬误,能够应用 get()函数。如果键不存在,则返回 None。也能够应用自定义音讯返回。

print (dic_a.get('Z'))
>>> None

# 自定义返回音讯
print (dic_a.get('Z', 'Key does not exist'))
>>> Key does not exist
拜访列表中的字典元素
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

list(dic_a.keys())[0]
>>> 'A'

list(dic_a.keys())[-1]
>>> 'C'

list(dic_a.values())[0]
>>> 'Apple'

list(dic_a.values())[-1]
>>> 'Cat'

3 删除字典元素

从字典中删除元素意味着一起删除一个键值对。

应用 del

能够应用 del 关键字和要删除其值的键删除字典元素。删除是in-place,这意味着删除后不须要重新分配字典的值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

# 删除“A”:“Apple”的键值对
del dic_a['A']

print (dic_a)
>>> {'B': 'Ball', 'C': 'Cat'}

# 删除“C”:“Cat”的键值对
del dic_a['C']

print (dic_a)
>>> {'B': 'Ball'}
应用 pop()

你还能够应用“pop()”函数删除元素。它返回弹出 (删除) 的值,并批改字典。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a.pop('A')
>>> 'Apple' 

print (dic_a)
# {'B': 'Ball', 'C': 'Cat'}

在上述两种办法中,如果要删除的键不存在于字典中,则会呈现 KeyError。在“pop()”的状况下,如果键不存在,能够指定要显示的谬误音讯。

key_to_delete = 'E'
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a.pop(key_to_delete, f'Key {key_to_delete} does not exist.')
>>> 'Key E does not exist.'
删除多个元素

没有间接的办法,然而你能够应用一个“for”循环,如下所示。

to_delete = ['A', 'C']
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

for key in to_delete:
    del dic_a[key]
    
print (dic_a)
>>> {'B': 'Ball'}

4 增加 / 插入新元素

你能够向字典中增加一个元素,如下所示。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a['D'] = 'Dog'

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

dic_a['E'] = 'Egg'

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Egg'}

如果你正在增加的键曾经存在,则将笼罩现有值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a['A'] = 'Adam' # 键“A”曾经存在,值为“Apple”print (dic_a)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}
应用 update()

还能够应用 update()函数通过将该对作为参数传递来增加新的键值对。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.update({'D': 'Dog'})

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

函数还容许你同时向现有字典增加多个键值对。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = {'D':'Dog', 'E':'Egg'}

dic_a.update(dic_b)

print(dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Egg'}

5 合并 / 连贯字典

能够应用从 Python 3.5 开始的解包操作符 (**) 合并两个或多个字典。

dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}

dic_merged = {**dic_a, **dic_b}

print (dic_merged)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

如果不想创立新字典,但只想将 dic_b 增加到现有 dic_a 中,你能够简略地更新后面所示的第一个字典。

dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}

dic_a.update(dic_b)

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
在连贯时如何解决反复键?

Python 字典的一个特点是它们不能有反复的键,即键不能呈现两次。那么,如果连贯两个或多个字典,其中蕴含一个或多个公共键,会产生什么状况。

答案是,最初一个合并字典中的键值对 (按合并程序) 将持续存在。在上面的示例中,所有三个字典中都存在键“A”,因而,最终字典从最初一个合并字典 (dic_c) 中获取值。

dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'A': 'Apricot'}
dic_c = {'A': 'Adam', 'E': 'Egg'}

dic_merged = {**dic_a, **dic_b, **dic_c}

print (dic_merged)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat', 'E': 'Egg'}
审慎的话

我刚说字典不能有反复的键。严格地说,你能够定义一个具备反复键的字典,然而,打印时,只能打印最初一个。如下所示的 dic_a,只返回惟一的键,对于反复的键(‘A),只返回最初一个值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'A': 'Apricot', 'A': 'Assault'}

print (dic_a)
>>> {'A': 'Assault', 'B': 'Ball'}
Python 3.9 中的更简略办法 +

从 Python 3.9 开始,你能够应用 | 操作符连贯两个或多个字典。

dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}

dic_c = dic_a | dic_b
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

# 连贯两个以上的字典
dic_d = dic_a | dic_b | dic_c

6 批改字典

如果要将“A”的值从“Apple”更改为“Apricot”,能够应用一个简略的赋值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_a['A'] = 'Apricot'

print (dic_a)
>>> {'A': 'Apricot', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

7 字典排序

字典中不保护程序。字典中不保护程序。你能够应用键或应用 sorted()函数的值对字典进行排序。

按键排序

如果键是字符串,它们将按字母程序排序。在字典中,咱们有两个次要元素:键和值。因而,在对键进行排序时,咱们应用第一个元素,即键,因而,lambda 函数中应用的索引是“[0]”。对于 lambda 函数的更多信息,能够浏览这篇文章。

dic_a = {'B': 100, 'C': 10, 'D': 90, 'A': 40}

sorted(dic_a.items(), key=lambda x: x[0])
>>> [('A', 40), ('B', 100), ('C', 10), ('D', 90)]

排序不是 in-place。如下所示,如果当初打印字典,它将放弃无序,与最后初始化时一样。你必须在分类后从新赋值。

# 如果你把这个字典打印进去,它还是没有程序
print (dic_a)
>>> {'B': 100, 'C': 10, 'D': 90, 'A': 40}

如果要按逆序排序,请指定关键字 reverse=True。

sorted(dic_a.items(), key=lambda x: x[0], reverse=True)
>>> [('D', 90), ('C', 10), ('B', 100), ('A', 40)]
按值排序

要依据字典的值对字典进行排序,须要在 lambda 函数中应用索引“[1]”。

dic_a = {'B': 100, 'C': 10, 'D': 90, 'A': 40}

sorted(dic_a.items(), key=lambda x: x[1])
>>> [('C', 10), ('A', 40), ('D', 90), ('B', 100)]

8 字典生成式

它是动态创建字典的一种十分有用的办法,也是动态创建字典的一种十分有用的办法。假如你要创立一个字典,其中键是一个整数,值是它的平方。字典生成式如下所示。

dic_c = {i: i**2 for i in range(5)}

print (dic_c)
>>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

如果你心愿你的键是字符串,能够应用 ’f-strings’。

dic_c = {f'{i}': i**2 for i in range(5)}

print (dic_c)
>>> {'0': 0, '1': 1, '2': 4, '3': 9, '4': 16}

9 创立字典的其余办法

从列表创立字典

假如你有两个列表,你想用它们创立一个字典。最简略的办法是应用 dict()构造函数。

names = ['Sam', 'Adam', 'Tom', 'Harry']
marks = [90, 85, 55, 70]

dic_grades = dict(zip(names, marks))

print (dic_grades)
>>> {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}

你还能够将这两个列表压缩在一起,并应用后面所示的字典生成式创立字典。

dic_grades = {k:v for k, v in zip(names, marks)}

print (dic_grades)
>>> {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}
传递键值对

你还能够将用逗号分隔的键值对列表传递给 dict()结构,它将返回一个字典。

dic_a = dict([('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')])

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

如果你的键是字符串,你甚至能够应用更简略的初始化,只应用变量作为键。

dic_a = dict(A='Apple', B='Ball', C='Cat')

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

10 复制字典

我将用一个简略的例子来解释这一点。字典的复制机制波及到更多的奥妙之处,我倡议读者参考这篇 Stack Overflow 的问题以取得具体的解释:https://stackoverflow.com/q/3…

参考赋值

当你只需将现有字典 (父字典) 从新指派给新字典时,两者都指向同一个对象(“援用赋值”)。

思考上面的例子,你将 dic_a 重新分配给 dic_b。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

dic_b = dic_a # 简略重新分配

当初,如果你批改 dic_b(例如增加一个新元素),你会留神到该更改也会反映在 dic_a 中。

dic_b['D'] = 'Dog'

print (dic_b)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
浅拷贝

应用 copy()函数创立一个浅拷贝。在浅拷贝中,这两个字典充当两个独立的对象,它们的内容依然共享雷同的援用。如果在新字典 (浅表正本) 中增加新的键值对,它将不会显示在父字典中。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()

dic_b['D'] = 'Dog'

# New,浅拷贝,有新的键值对
print (dic_b)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

# 父字典没有新的键值对
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

当初,父字典 (“dic_a”) 中的内容是否会更改取决于值的类型。例如,在上面,内容是不可变的简略字符串。因而,更改给定键 (在本例中为 a) 的“dic_b”中的值不会更改“dic_a”中键“a”的值。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()

# 在浅拷贝中将现有键替换为新值
dic_b['A'] = 'Adam'

print (dic_b)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}

# 字符串是不可变的,所以 'Apple' 在 dic_a 中不会变成 'Adam'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}

然而,如果“dic_A”中键“A”的值是一个列表,那么在“dic_b”中更改其值将反映“dic_A”(父字典)中的更改,因为列表是可变的。

dic_a = {'A': ['Apple'], 'B': 'Ball', 'C': 'Cat'}

# 浅拷贝
dic_b = dic_a.copy()

dic_b['A'][0] = 'Adam'

print (dic_b)
>>> {'A': ['Adam'], 'B': 'Ball', 'C': 'Coal'}

# 列表是可变的,因而更改也会反映在 dic_a 中
print (dic_a)
>>> {'A': ['Adam'], 'B': 'Ball', 'C': 'Cat'}

11 重命名现有键

假如你想将键“Adam”替换为“Alex”。你能够应用 pop 函数,因为它删除传递的键 (这里是 Adam) 并返回删除的值(这里是 85)。所以你一枪打死两只鸟。

应用返回的 (已删除) 值将该值调配给新键(这里是 Alex)。可能还有更简单的状况,其中的键是元组。这种状况不在本文的探讨范畴之内。

dic_a = {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}

dic_a['Alex'] = dic_a.pop('Adam')

print (dic_a)
>>> {'Sam': 90, 'Tom': 55, 'Harry': 70, 'Alex': 85}

12 嵌套字典

嵌套字典在一个字典中有一个或多个字典。上面是具备两层嵌套的嵌套字典的最简略示例。这里,内部字典 (第 1 层) 只有一个键值对。然而,当初值自身就是一个字典。

dic_a = {'A': {'B': 'Ball'}}

dic_a['A']
>>> {'B': 'Ball'}

type(dic_a['A'])
>>> dict

如果你想进一步拜访外部字典 (第 2 层) 的键值对,当初须要应用 dic_a[‘a’]作为字典。

dic_a['A']['B']
>>> 'Ball'
三层字典

让咱们增加一个嵌套字典的附加层。当初,dic_a[‘a’]自身是一个嵌套字典,与下面最简略的嵌套字典不同。

dic_a = {'A': {'B': {'C': 'Cat'}}}

# 第 1 层
dic_a['A']
>>> {'B': {'C': 'Cat'}}

# 第 2 层
dic_a['A']['B']
>>> {'C': 'Cat'}

# 第 3 层
dic_a['A']['B']['C']
>>> 'Cat'

13 查看字典中是否存在键

你能够应用 in 运算符查找字典中是否存在特定键。

dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}

'A' in dic_a
# True

'E' in dic_a
# False

在下面的代码中,你不须要应用“in dic_a.keys()”,因为“in dic_a”曾经在键中查找了。

原文链接:https://towardsdatascience.co…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

退出移动版