个性化阅读
专注于IT技术分析

Python字典深入理解教程

本文概述

字典(或Python中的dict)是一种存储元素的方式, 就像在Python列表中一样。但是, 不是使用索引来访问元素, 而是为其分配了固定的键, 然后使用该键来访问元素。你现在要处理的是一个”键-值”对, 有时它是解决许多问题的更合适的数据结构, 而不是简单的列表。进行数据科学时, 你通常必须处理字典, 这使字典理解成为你想要掌握的技能。

在本教程中:

  • 首先, 你将了解真正的Python字典以及如何有效使用它。
  • 接下来, 你将了解Python字典理解:你将了解它的含义, 为什么重要以及如何将其用作for循环和lambda函数的替代方法。
  • 你将学习如何将条件添加到字典理解中:你将使用if条件, 多个if条件以及if-else语句。
  • 最后, 你将了解什么是嵌套字典理解, 如何使用它以及如何使用for循环重写它。

让我们开始吧…

Python字典

Python中的字典是通过特定键而不是通过索引访问的项的集合。这是什么意思?

想象一下现实世界中的字典…当你需要查找单词的含义时, 你尝试使用单词本身而不是单词的可能索引来查找含义。 Python词典使用相同的概念, 你要查找其含义的单词是键, 而单词的含义是值, 你无需知道字典中单词的索引即可查找其含义。

注意:字典中的键必须是可哈希的。

散列是通过特定类型的功能运行项目的过程。该函数称为”哈希函数”。该哈希函数返回唯一输入值的唯一输出。整数, 浮点数, 字符串, 元组和Frozensets是可哈希的。而列表, 字典和除冻结集以外的集合则不是。散列是一个有点复杂的话题, 这只是散列背后的基本概念。

你可以通过以下方式在Python中初始化字典:

a = {'apple': 'fruit', 'beetroot': 'vegetable', 'cake': 'dessert'}
a['doughnut'] = 'snack'
print(a['apple'])
fruit
print(a[0])
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

<ipython-input-9-00d4a978143a> in <module>()
----> 1 print(a[0])


KeyError: 0

请注意, 上面的代码行会向你显示错误消息, 因为不存在键” 0″。

词典中的项目可以具有任何数据类型。查看字典的更多示例以了解更多信息:

a = {'one': 1, 'two': 'to', 'three': 3.0, 'four': [4, 4.0]}
print(a)
{'four': [4, 4.0], 'two': 'to', 'three': 3.0, 'one': 1}
# Update a dictionary
a['one'] = 1.0 
print(a)
{'four': [4, 4.0], 'two': 'to', 'three': 3.0, 'one': 1.0}
# Delete a single element
del a['one'] 
print(a)
{'four': [4, 4.0], 'two': 'to', 'three': 3.0}
# Delete all elements in the dictionary
a.clear()
print(a)
{}
# Delete the dictionary
del a 
print(a)
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-12-701c9d6596da> in <module>()
      1 del a #Deletes the dictionary
----> 2 print(a)


NameError: name 'a' is not defined

要记住的重要一点是, 密钥在字典中必须是唯一的, 不允许重复。但是, 在重复键而不是给出错误的情况下, Python会将键的最后一个实例视为有效, 而只是忽略第一个键值对。亲自查看:

sweet_dict = {'a1': 'cake', 'a2':'cookie', 'a1': 'icecream'}
print(sweet_dict['a1'])
icecream

如果你想进一步了解Python中的词典, 请查阅本教程。

Python字典理解

词典理解是一种将一个词典转换为另一本词典的方法。在此转换过程中, 原始词典中的项目可以有条件地包含在新词典中, 并且每个项目都可以根据需要进行转换。

良好的列表理解可以使你的代码更具表现力, 因此更易于阅读。产生理解力的关键是不要让它们变得如此复杂, 以至于当你试图破译它们实际在做什么时, 你的头会旋转。保持”易于阅读”的想法。

在Python中执行字典理解的方法是能够访问字典的键对象和值对象。

如何才能做到这一点?

Python覆盖了你!你可以简单地使用内置方法:

dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
# Put all keys of `dict1` in a list and returns the list
dict1.keys()
dict_keys(['c', 'd', 'a', 'b'])
# Put all values saved in `dict1` in a list and returns the list
dict1.values()
dict_values([3, 4, 1, 2])

因此, 既然你知道如何访问字典中的所有键及其值。你还可以使用items()方法访问字典中的每个键值对:

dict1.items()
dict_items([('c', 3), ('d', 4), ('a', 1), ('b', 2)])

这是你可以在Python中理解字典的通用模板:

dict_variable = {key:value for (key, value) in dictonary.items()}

这可以用作基本和最简单的模板。当你添加条件时, 它会变得越来越复杂。

让我们从一个简单的字典理解开始:

dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Double each value in the dictionary
double_dict1 = {k:v*2 for (k, v) in dict1.items()}
print(double_dict1)
{'e': 10, 'a': 2, 'c': 6, 'b': 4, 'd': 8}

在上面的理解代码中, 你可以通过简单地将字典dict1中的每个值加倍来从字典dict1中创建新字典double_dict1。

你还可以更改键值。例如, 让我们创建与上述相同的字典, 但还要更改键的名称。

dict1_keys = {k*2:v for (k, v) in dict1.items()}
print(dict1_keys)
{'dd': 4, 'ee': 5, 'aa': 1, 'bb': 2, 'cc': 3}

为什么要使用字典理解?

字典理解是一个强大的概念, 可用于替代循环和lambda函数。但是, 并非所有的for循环都可以编写为字典理解, 但是所有的字典理解都可以使用for循环编写。

考虑以下问题, 你想创建一个新字典, 其中的键是一个数字, 该数字可以被2整除, 范围为0-10, 其值是该数字的平方。

让我们看看如何使用for循环和字典理解来解决相同的探针:

numbers = range(10)
new_dict_for = {}

# Add values to `new_dict` using for loop
for n in numbers:
    if n%2==0:
        new_dict_for[n] = n**2

print(new_dict_for)
{0: 0, 8: 64, 2: 4, 4: 16, 6: 36}
# Use dictionary comprehension
new_dict_comp = {n:n**2 for n in numbers if n%2 == 0}

print(new_dict_comp)
{0: 0, 8: 64, 2: 4, 4: 16, 6: 36}

for循环的替代方法

For循环用于将给定次数重复执行某个程序中的某个操作或指令块。但是, 嵌套的for循环(在另一个for循环内的for循环)可能会造成混乱和复杂。在这种情况下, 词典理解会更好, 并且可以简化可读性和对代码的理解。

提示:查阅srcmini的Python循环教程, 了解有关Python循环的更多信息。

Lambda函数的替代方法

Lambda函数是创建小型匿名函数的一种方式。它们是没有名称的函数。这些函数是一次性函数, 仅在创建它们时才需要。 Lambda函数主要与filter(), map()和reduce()函数结合使用。

让我们看一下lambda函数以及map()函数:

# Initialize `fahrenheit` dictionary 
fahrenheit = {'t1':-30, 't2':-20, 't3':-10, 't4':0}

#Get the corresponding `celsius` values
celsius = list(map(lambda x: (float(5)/9)*(x-32), fahrenheit.values()))

#Create the `celsius` dictionary
celsius_dict = dict(zip(fahrenheit.keys(), celsius))

print(celsius_dict)
{'t2': -28.88888888888889, 't3': -23.333333333333336, 't1': -34.44444444444444, 't4': -17.77777777777778}

让我们看看另一种情况, 你要将华氏温度的字典转换为摄氏度。

让我们分解一下代码:首先, 你需要定义一个数学公式来完成从华氏度到摄氏度的转换。在代码中, 这是在lambda函数的帮助下完成的。然后, 将此函数作为参数传递给map()函数, 该函数随后将操作应用于fahrenheit.values()列表中的每个项目。

还记得values()函数吗?它返回一个列表, 其中包含存储在字典中的项目。

你现在所拥有的是一个包含摄氏温度值的列表, 但是解决方案要求它必须是字典。 Python具有一个称为zip()的内置函数, 该函数遍历迭代器的元素并将其聚合。你可以在此处阅读有关zip()函数的更多信息。在上面的示例中, zip函数将fahrenheit.keys()和celsius列表中的项聚合在一起, 提供了一个键值对, 你可以使用dict函数将其组合到字典中, 这是理想的结果。

现在, 让我们尝试使用字典理解来解决相同的问题:

# Initialize the `fahrenheit` dictionary 
fahrenheit = {'t1': -30, 't2': -20, 't3': -10, 't4': 0}

# Get the corresponding `celsius` values and create the new dictionary
celsius = {k:(float(5)/9)*(v-32) for (k, v) in fahrenheit.items()}

print(celsius_dict)
{'t2': -28.88888888888889, 't3': -23.333333333333336, 't1': -34.44444444444444, 't4': -17.77777777777778}

如你所见, 与两步过程相比, 使用字典理解可以用一行代码解决问题, 并且可以理解第一个实现的三个函数(lambda, map()和zip())的工作。

此外, 该解决方案直观易懂, 并且易于理解词典。因此, 字典理解可以作为lambda函数的一个很好的选择。

在字典理解中添加条件

解决问题时, 通常需要为解决方案添加条件。让我们探索如何将条件添加到字典理解中以使其更强大。

如果条件

假设你需要根据给定的字典创建一个新字典, 但其项大于2。这意味着你需要为上面看到的原始模板添加一个条件…

dict1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

# Check for items greater than 2
dict1_cond = {k:v for (k, v) in dict1.items() if v>2}

print(dict1_cond)
{'e': 5, 'c': 3, 'd': 4}

这并不难!但是, 如果你有多个条件怎么办?

多条件

在上面的问题中, 如果你不仅需要获得大于2的项目, 还需要同时检查它们是否为2的倍数, 该怎么办?

dict1_doubleCond = {k:v for (k, v) in dict1.items() if v>2 if v%2 == 0}
print(dict1_doubleCond)
{'d': 4}

添加多个条件的解决方案就像在理解中简单地一个接一个地添加条件一样容易。但是, 你需要谨慎对待问题中要采取的措施。请记住, 连续的if语句就像它们之间有and子句一样工作。

让我们再看一个带有三个条件的示例:

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

dict1_tripleCond = {k:v for (k, v) in dict1.items() if v>2 if v%2 == 0 if v%3 == 0}

print(dict1_tripleCond)
{'f': 6}

在for循环中, 这将对应于:

dict1_tripleCond = {}

for (k, v) in dict1.items():
    if (v>=2 and v%2 == 0 and v%3 == 0):
            dict1_tripleCond[k] = v

print(dict1_tripleCond)
{'f': 6}

如果-其他条件

通过字典理解, 处理if-else条件也很容易。查看以下示例, 亲自看看:

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

# Identify odd and even entries
dict1_tripleCond = {k:('even' if v%2==0 else 'odd') for (k, v) in dict1.items()}

print(dict1_tripleCond)
{'f': 'even', 'c': 'odd', 'b': 'even', 'd': 'even', 'e': 'odd', 'a': 'odd'}

嵌套字典理解

嵌套是一种编程概念, 其中数据按层组织, 或者对象包含其他类似对象。你必须经常看到嵌套的” if”结构, 这是另一个if条件中的一个if条件。

同样, 字典可以嵌套, 因此它们的理解也可以嵌套。让我们看看这意味着什么:

nested_dict = {'first':{'a':1}, 'second':{'b':2}}
float_dict = {outer_k: {float(inner_v) for (inner_k, inner_v) in outer_v.items()} for (outer_k, outer_v) in nested_dict.items()}
print(float_dict)
{'first': {1.0}, 'second': {2.0}}

这是嵌套字典的示例。 nested_dict是具有以下键的字典:first和second, 它们将字典对象保存在其值中。该代码使用内部字典值并将其转换为float, 然后将外部键与新的float内部值组合为新的字典。

该代码还具有嵌套的字典理解, 这是另一个字典内部的字典理解。如你所见, 嵌套时的字典理解会变得很难阅读和理解, 这首先消除了使用理解的全部意义。随着你正在使用的字典的结构变得复杂, 字典的理解也开始变得复杂。在这种情况下, 最好不要在代码中使用复杂的理解。

请注意, 你还可以使用嵌套的for循环来重写上述代码块:

nested_dict = {'first':{'a':1}, 'second':{'b':2}}

for (outer_k, outer_v) in nested_dict.items():
    for (inner_k, inner_v) in outer_v.items():
        outer_v.update({inner_k: float(inner_v)})
nested_dict.update({outer_k:outer_v})

print(nested_dict)
{'first': {'a': 1.0}, 'second': {'b': 2.0}}

本文总结

现在, 借助字典理解-SUN, 你将更加明亮!恭喜你完成了本教程。你已经了解了Python中的字典, 理解的概念以及原因, 其中理解在处理字典时特别有用。现在你可以有效地处理Python字典了。

练习可以使你的Python更好!如果还没有, 请查看srcmini的日常练习模式!通过日常练习模式, 你可以通过交互式编码挑战使学习更加有效。所以, 去玩吧!

赞(0)
未经允许不得转载:srcmini » Python字典深入理解教程

评论 抢沙发

评论前必须登录!