python字典包含字典
Python offers a variety of data structures to hold our information —the dictionary being one of the most useful. Python dictionaries quick, easy to use, and flexible. As a beginning programmer, you can use this Python tutorial to become familiar with dictionaries and their common uses so that you can start incorporating them immediately into your own code.
Python提供了各种数据结构来保存我们的信息-字典是最有用的字典之一。 Python字典快速,易于使用且灵活。 作为入门程序员,您可以使用此Python教程来熟悉字典及其常见用法,以便立即开始将它们合并到自己的代码中。
When performing data analysis, you’ll often have data that is an unusable or hard-to-use form. Dictionaries can help here, by making it easier to read and change your data.
在执行数据分析时,您经常会得到无法使用或难以使用的数据。 字典可以通过简化读取和更改数据的方式来提供帮助。
For this tutorial, we will use the Craft Beers data sets from Kaggle. There is one data set describing beer characterstics, and another that stores geographical information on brewery companies. For the purposes of this article, our data will be stored in thebeers
andbreweries
variables, each as a list of lists. The tables below give a quick look at what the data look like.
在本教程中,我们将使用Kaggle的Craft Beers数据集 。 有一个描述啤酒特性的数据集,另一个存储了啤酒公司的地理信息。 就本文而言,我们的数据将存储在beers
和breweries
变量中,每个变量均作为列表列表。 下表快速查看了数据的外观。
This table contains the first row from thebeers
data set.
该表包含beers
数据集的第一行。
This table contains the first row from thebreweries
data set.
该表包含breweries
数据集的第一行。
必备知识 (Prerequisite knowledge)
This article assumes basic knowledge of Python. To fully understand the article, you should be comfortable working with lists andfor
loops.
本文假定您具有Python的基本知识。 为了完全理解本文,您应该习惯使用列表和for
循环。
We’ll cover:
我们将介绍:
Key terms and concepts to dictionaries Dictionary rules Basic dictionary operations creation and deletionaccess and insertionmembership checking Looping techniquesDictionary comprehensionsDictionary advantages and disadvantages 词典的关键术语和概念 字典规则 基本字典操作 创建和删除 访问和插入 会员检查 循环技术 字典理解 词典的优缺点
成为我们的角色 (Getting into our role)
We will assume the role of a reviewer for a beer enthusiast magazine. We want to know ahead of time what each brewery will have before we arrive to review, so that we can gather useful background information. Our data sets hold information on beers and breweries, but the data themselves are not immediately accessible.
我们将担任啤酒爱好者杂志的审稿人。 我们想提前知道每个啤酒厂将要到达的内容,以便我们收集有用的背景信息。 我们的数据集包含有关啤酒和啤酒厂的信息,但数据本身无法立即访问。
The data are currently in the form of a list of lists. To access individual data rows, you must use a numbered index. To get the first data row ofbreweries
, you look at the 2nd item (the column names are first).
数据当前为列表列表的形式。 要访问单个数据行,必须使用数字索引。 要获得breweries
的第一个数据行,请查看第二个项目(列名称为第一列)。
breweries[1]
breweries[1]
breweries[1]
is a list, so you can also index from it as well. Getting the third item in this list would look like:
breweries[1]
是一个列表,因此您也可以从中进行索引。 获取此列表中的第三项将类似于:
If you didn’t know thatbreweries
was data on breweries, you’d have a hard time understanding what the indexing is trying to do. Imagine writing this code and looking at it again 6 months in the future. You’re more than likely to forget, so it merits us reformatting the data in a more readable way.
如果您不知道breweries
是breweries
数据,那么您将很难理解索引的作用。 想象一下编写此代码,然后在六个月后再次查看它。 您极有可能会忘记,所以它值得我们以一种更具可读性的方式重新格式化数据。
关键术语和概念 (Key terms and concepts)
Dictionaries are made up ofkey-value pairs. Looking at the key in a Python dictionary is akin to the looking for a particular word in a physical dictionary. The value is the corresponding data that is associated with the key, comparable to the definition associated with the word in the physical dictionary. The key is what we look up, and it’s the value that we’re actually interested in.
字典由键值对组成。 在Python字典中查找键类似于在物理词典中查找特定单词。 该值是与键相关联的对应数据,可以与与物理词典中的单词相关联的定义进行比较。 关键是我们要查找的内容,这是我们真正感兴趣的价值。
We say that values are mapped to keys. In the example above, if we look up the word “programmer” in the English dictionary, we’ll see: “a person who writes computer programs.” The word “programmer” is the key mapped to the definition of the word.
我们说值被映射到键。 在上面的示例中,如果我们在英语词典中查找“ programmer”一词,则会看到:“一个编写计算机程序的人。” “程序员”一词是映射到该词定义的键。
键和值的字典规则 (Dictionary rules for keys and values)
Dictionaries are immensely flexible because they allow anything to be stored as a value, from primitive types like strings and floats to more complicated types like objects and even other dictionaries (more on this later).
字典具有极大的灵活性,因为它们允许将任何东西都存储为值,从原始类型(如字符串和浮点数)到更复杂的类型(如对象,甚至其他字典)(稍后将对此进行详细介绍)。
By contrast, there are limitations to what can be used as a key.
相比之下,可以用作密钥的内容存在限制。
A key is required to be animmutableobject in Python, meaning that it cannot be alterable. This rule allows strings, integers, and tuples as keys, but excludes lists and dictionaries since they aremutable, or able to be altered. The rationale is simple: if any changes happen to a key without you knowing, you won’t be able to access the value anymore, rendering the dictionary useless. Thus, only immutable objects are allowed to be keys. A key must also be unique within a dictionary.
键必须是Python中的不可变对象,这意味着它不可更改。 此规则允许将字符串,整数和元组作为键,但排除列表和字典,因为它们是可变的或可以更改的。 基本原理很简单:如果在您不知情的情况下对键进行了任何更改,您将无法再访问该值,从而使字典无用。 因此,只允许不可变的对象作为键。 键在字典中也必须是唯一的。
The key-value structuring of a dictionary is what makes it so powerful, and throughout this post we’ll delve into its basic operations, use cases, and their advantages and disadvantages.
字典的键值结构使它变得如此强大,并且在本博文中,我们将深入研究其基本操作,用例及其优缺点。
基本字典操作 (Basic dictionary operations)
创建和删除 (Creation and deletion)
Let’s start with how to create a dictionary. First, we will learn how to make an empty dictionary since you’ll often find that you want to start with an empty one and populate with data as needed.
让我们从如何创建字典开始。 首先,我们将学习如何制作空字典,因为您经常会发现自己想从空字典开始,并根据需要填充数据。
To create an empty dictionary, we can either use thedict()
function with no inputs, or assign a pair of curly brackets with nothing in between to a variable. We can confirm that both methods will produce the same result.
要创建一个空字典,我们可以使用没有输入的dict()
函数,或者为变量分配一对大括号,而大括号之间不包含任何内容。 我们可以确认这两种方法将产生相同的结果。
empty = {}also_empty = dict()empty == also_empty>>> True
empty = {}also_empty = dict()empty == also_empty>>> True
Now, an empty dictionary isn’t of much use to anybody, so we must add our own key-value pairs. We will cover this later in the article, but know that we are able to start with empty dictionaries and populate them after the fact. This will allow us to add in more information when we need it.
现在,空字典对任何人都没有多大用处,因此我们必须添加自己的键值对。 我们将在文章的后面对此进行介绍,但是知道我们可以从空字典开始,然后在事实之后填充它们。 这将使我们能够在需要时添加更多信息。
Alternatively, you can also create a dictionary and pre-populate it with key-value pairs. There are two ways to do this.
另外,您也可以创建字典并用键值对预先填充它。 有两种方法可以做到这一点。
The first is to use brackets containing the key-value pairs. Each key and value are separated by a:
, while individual pairs are separated by a comma. While you can fit everything on one line, it’s better to split up your key-value pairs among different lines to improve readability.
第一种是使用包含键值对的方括号。 每个键和值都用:
分隔,而各个对则用逗号分隔。 尽管您可以将所有内容放在一行中,但最好将键值对拆分成不同的行以提高可读性。
data = {"beer_data": beers,"brewery_data": breweries}
data = {"beer_data": beers,"brewery_data": breweries}
The above code creates a single dictionary,data
, where our keys are descriptive strings and the values are our data sets. This single dictionary allows us to access both data sets by name.
上面的代码创建了一个字典data
,其中我们的键是描述性字符串,而值是我们的数据集。 这个单一的字典使我们可以按名称访问两个数据集。
The second way is through thedict()
method. You can supply the keys and values either as keyword arguments or as a list of tuples. We will recreate thedata
dictionary from above using thedict()
methods and providing the key-value pairs appropriately.
第二种方法是通过dict()
方法。 您可以将关键字和值作为关键字参数或作为元组列表提供。 我们将使用dict()
方法从上方重新创建data
字典,并适当提供键值对。
We can confirm that each of thedata
dictionaries are equivalent in Python’s eyes.
我们可以确认每个data
字典在Python眼中都是等效的。
data == data2 == data3>>> True
data == data2 == data3>>> True
With each option, the key and value pairs must be formatted in a particular way, so it’s easy to get mixed up. The diagram below helps to sort out where keys and values are in each.
对于每个选项,键和值对必须以特定的方式设置格式,因此很容易混淆。 下图有助于弄清键和值在每个位置。
We now have three dictionaries storing the exact same information, so it’s best if we just keep one. Dictionaries themselves don’t have a method for deletion, but Python provides thedel
statement for this purpose.
现在,我们有3个字典存储完全相同的信息,因此最好只保留1个。 字典本身没有删除方法,但是Python为此提供了del
语句。
After creating your dictionaries, you’ll almost certainly need to add and remove items from them. Python provides a simple, readable syntax for these operations.
创建字典后,几乎可以肯定需要添加和删除字典中的项目。 Python为这些操作提供了一种简单易懂的语法。
数据访问和插入 (Data access and insertion)
The current state of our beers and breweries dictionary is still dire —each of the data sets originally was a list of lists, which makes it difficult to access specific data rows.
我们的啤酒和啤酒厂字典的当前状态仍然很糟—每个数据集最初都是列表列表,这使得很难访问特定的数据行。
We can achieve better structure by reorganizing each of the data sets into its own dictionary and creating some helpful key-value pairs to describe the data within the dictionary. The raw data itself is mixed. The first row in each list of lists is a list of strings containing the column names, but the rest contains the actual data. It’ll be better to separate the columns from the data so we can be more explicit. Thus, for each data set, we’ll create a dictionary with three keys mapped to the following values:
通过将每个数据集重新组织到其自己的字典中并创建一些有用的键值对来描述字典中的数据,我们可以获得更好的结构。 原始数据本身是混合的。 每个列表列表中的第一行是包含列名称的字符串列表,而其余部分包含实际数据。 最好将列与数据分开,这样我们可以更加明确。 因此,对于每个数据集,我们将创建一个字典,其中三个键映射到以下值:
The raw data itselfThe list containing the column namesThe list of lists containing the rest of the data 原始数据本身 包含列名的列表 包含其余数据的列表列表
beer_details = {"raw_data": beers,"columns": beers[0],"data": beers[1:]}brewery_details = {"raw_data": breweries,"columns": breweries[0],"data": breweries[1:]}
beer_details = {"raw_data": beers,"columns": beers[0],"data": beers[1:]}brewery_details = {"raw_data": breweries,"columns": breweries[0],"data": breweries[1:]}
Now, we can reference thecolumns
key explicitly to list the column names of the data instead of indexing the first item inraw_data
. Similarly, we are now able to explicitly ask for just the data from thedata
key.
现在,我们可以显式引用columns
键以列出数据的列名,而不是为raw_data
的第一项编制索引。 同样,我们现在可以显式地仅从data
键中请求data
。
So far, we’ve learned how to create empty and prepopulated dictionaries, but we do not know how to read information from them once they’ve been made. To access items within a dictionary, we needbracket notation. We reference the dictionary itself followed by a pair of brackets with the key that we want to look up. For example below, we read the column names frombrewery_details
.
到目前为止,我们已经学习了如何创建空的和预填充的字典,但是一旦制作完成,我们还不知道如何从中读取信息。 要访问字典中的项目,我们需要使用括号符号。 我们引用字典本身,后跟带有要查找的键的方括号。 例如,在下面的示例中,我们从brewery_details
读取列名。
This action should feel similar to us looking up a word in a English dictionary. We “looked up” a key and got the information we wanted back in the mapped value.
此操作应类似于我们在英语词典中查找单词的感觉。 我们“查找”了一个键,并在映射值中获得了我们想要的信息。
In addition to looking up key-value pairs, sometimes we’ll actually want to change the value associated with a key in our dictionaries. This operation also uses bracket notation. To change a dictionary value, we first access the key and then reassign it using an=
expression.
除了查找键值对之外,有时我们实际上还想更改字典中与键关联的值。 此操作也使用括号符号。 要更改字典值,我们首先访问键,然后使用=
表达式重新分配它。
We saw in the code above that one of the brewery columns is an empty string, but this first column actually contains a unique ID for each brewery! We will reassign the first column name to a more informative name.
我们在上面的代码中看到,啤酒厂列中的一个是空字符串,但是第一列实际上包含每个啤酒厂的唯一ID! 我们将第一列名称重新分配给更多信息的名称。
# reassigning the first column of the breweries data setbrewery_details["columns"][0] = 'brewery_id'# confirming that our reassignment workedbrewery_details["columns"][0]>>> "brewery_id"
# reassigning the first column of the breweries data setbrewery_details["columns"][0] = 'brewery_id'# confirming that our reassignment workedbrewery_details["columns"][0]>>> "brewery_id"
If the series of brackets looks confusing, don’t fret. We have taken advantage of nesting. We know that thecolumns
key inbrewery_details
is mapped to a list, so we can treatbrewery_details["columns"]
as a list (i.e. we can use list indexing). Nesting can get confusing if we lose track of what each level represents, but we visualize this nesting below to clarify.
如果一系列的括号看起来令人困惑,请不要担心。 我们利用了嵌套的优势。 我们知道brewery_details
中的columns
键已映射到列表,因此我们可以将brewery_details["columns"]
视为列表(即,可以使用列表索引)。 如果我们无法跟踪每个级别代表的内容,则嵌套会引起混乱,但是我们在下面将其可视化以进行澄清。
It’s also common practice to nest dictionaries within dictionaries because it createsself-documentingcode. That is to say, it is evident what the code is doing just by reading it, without any comments to help. Self-documenting code is immensely useful because it is easier and faster to understand at a moment’s read through. We want to preserve this self-documenting quality, so we will nest thebeer_details
andbrewery_details
dictionaries into a centralized dictionary. The end result are nested dictionaries that are easier to read from than the original raw data itself.
将字典嵌套在字典中也是一种常见的做法,因为它会创建自文档代码。 也就是说,很明显,仅通过阅读代码即可完成代码的工作,而无需任何注释。 自记录代码非常有用,因为它可以让您在阅读时更容易,更快地理解。 我们希望保留这种自我记录的质量,因此我们将beer_details
和brewery_details
字典嵌套在集中式词典中。 最终结果是嵌套字典,比原始原始数据本身更易于读取。
The information embeded in the code is clear if we nest dictionaries within dictionaries. We’ve created a structure that easily describes the intent of the programmer. The following illustration breaks down the dictionary nesting.
如果我们将字典嵌套在字典中,则代码中嵌入的信息将很清晰。 我们创建了一个结构,可以轻松描述程序员的意图。 下图说明了字典的嵌套。
From here on out, we’ll usedatasets
to manage our data sets and perform more data reorganization.
从现在开始,我们将使用datasets
来管理数据集并执行更多的数据重组。
The beer and brewery dictionaries we made are a good start, but we can do more. We’d like to create a new key-value pair to contain a string description of what each data set contains in case we forget.
我们制作的啤酒和啤酒词典是一个好的开始,但是我们可以做更多。 我们希望创建一个新的键值对,以包含每个数据集包含的字符串描述,以防万一。
We can create dictionaries and read and change values of present key-value pairs, but we don’t know how to insert a new key-value pair. Thankfully, inserting pairs is similar to reassigning dictionary values. If we assign a value to a key that doesn’t exist in a dictionary, Python will take the new key and value and create the pair within the dictionary.
我们可以创建字典并读取和更改当前键值对的值,但是我们不知道如何插入新的键值对。 幸运的是,插入对类似于重新分配字典值。 如果我们为字典中不存在的键分配一个值,Python将获取新的键和值并在字典中创建该对。
# The description key currently does not exist in either the inner dictionarydatasets["beer"]["description"] = "Contains data on beers and their qualities"datasets["breweries"]["description"] = "Contains data on breweries and their locations"
# The description key currently does not exist in either the inner dictionarydatasets["beer"]["description"] = "Contains data on beers and their qualities"datasets["breweries"]["description"] = "Contains data on breweries and their locations"
While Python makes it easy to insert new pairs into the dictionary, it stops users if they try to access keys that don’t exist. If you try to access a key that doesn’t exist, Python will throw an error and stop your code from running.
尽管Python可以轻松地将新对插入字典中,但是如果用户尝试访问不存在的键,它将阻止用户。 如果您尝试访问不存在的密钥,Python将抛出错误并停止运行代码。
As your dictionaries get more complex, it’s easier to lose track of which keys are present. If you leave your code for a week and forget what’s in your dictionary, you’ll constantly run intoKeyErrors
. Thankfully, Python provides us with an easy way to check the present keys in a dictionary. This process is called membership checking.
随着您的词典变得越来越复杂,更容易弄清存在哪些键。 如果您将代码保留一周,却忘记了字典中的内容,则会不断遇到KeyErrors
。 幸运的是,Python为我们提供了一种简便的方法来检查字典中的当前键。 此过程称为成员资格检查。
会员资格检查 (Membership checking)
If we want to check if a key exists within a dictionary, we can use thein
operator. You can also check on whether a key doesn’t exist by usingnot in
. The resulting code reads almost like natural English, which also means it is easier to understand at first glance.
如果要检查字典中是否存在键,可以使用in
运算符。 您还可以通过使用not in
来检查键是否不存在。 生成的代码读起来几乎像自然的英语,这也意味着乍一看更容易理解。
"beer" in datasets>>> True"wine" in datasets>>> False"wine" not in datasets>>> True
"beer" in datasets>>> True"wine" in datasets>>> False"wine" not in datasets>>> True
Usingin
for membership checking has great utility in conjunction withif-else
statements. This combination allows you to set up conditional logic that will prevent you from gettingKeyErrors
and enable you to make more sophisticated code. We won’t delve too deeply into this concept, but there’s resources at the end for the curious.
与inif-else
语句结合使用in
进行成员资格检查很有用。 这种组合使您可以设置条件逻辑,以防止获取KeyErrors
并使您能够编写更复杂的代码。 我们不会深入研究这个概念,但是最后有很多好奇的资源。
章节摘要 (Section summary)
At this point, we know how to create, read, update, and delete data from our dictionaries. We transformed our two raw data sets into dictionaries with greater readability and ease of use. With these basic dictionary operations, we can start performing more complex operations. For example, it is extremely common to want to loop over the key-value pairs and perform some operation on each pair.
至此,我们知道了如何从字典中创建,读取,更新和删除数据。 我们将两个原始数据集转换为字典,具有更高的可读性和易用性。 通过这些基本的字典操作,我们可以开始执行更复杂的操作。 例如,非常常见的是要遍历键值对并在每个对上执行一些操作。
循环技术 (Looping techniques)
When we created thedescription
key for each of the data sets, we made two individual statements to create each key-value pair. Since we performed the same operation, it would be more efficient to use loops.
当我们为每个数据集创建description
键时,我们做出了两个单独的语句来创建每个键值对。 由于我们执行了相同的操作,因此使用循环会更有效。
Python provides three main methods to use dictionaries in loops:keys()
,values()
, anditems()
. Usingkeys()
andvalues()
allows us to loop over those parts of the dictionary.
Python提供了三种在循环中使用字典的主要方法:keys()
,values()
和items()
。 使用keys()
和values()
允许我们遍历字典的那些部分。
Theitems()
method combines both into one. When used in a loop,items()
returns the key-value pairs as tuples. The first element of this tuple is the key, while the second is the value. We can use destructuring to get these elements into properly informative variable names. The first variablekey
will take the key in the tuple, whileval
will get the mapped value.
items()
方法将两者结合在一起。 在循环中使用时,items()
将键值对作为元组返回。 该元组的第一个元素是键,而第二个是值。 我们可以使用解构将这些元素转换为内容丰富的变量名。 第一个变量key
将把键作为元组中的键,而val
将获得映射的值。
for key, val in datasets.items():print(f'The {key} data set has {len(val["data"])} rows.')>>> The beer data set has 2410 rows.>>> The breweries data set has 558 rows.
for key, val in datasets.items():print(f'The {key} data set has {len(val["data"])} rows.')>>> The beer data set has 2410 rows.>>> The breweries data set has 558 rows.
The above loop tells us that the beer data set is much bigger than the brewery data set. We would expect breweries to sell multiple types of beers, so there should be more beers than breweries overall. Our loop confirms this thought.
上面的循环告诉我们,啤酒数据集比啤酒厂数据集大得多。 我们希望啤酒厂出售多种类型的啤酒,因此啤酒应该比啤酒厂总体上更多。 我们的循环证实了这一想法。
Currently, each of the data rows are a list, so referencing these elements by number is undesirable. Instead, we’ll turn each of the data rows into its own dictionary, with the column name mapped to its actual value. This would make analyzing the data easier in the long run.
当前,每个数据行都是一个列表,因此不希望通过数字引用这些元素。 取而代之的是,我们将每个数据行转换成自己的字典,并将列名映射到其实际值。 从长远来看,这将使数据分析更加容易。
We should do this operation on both data sets, so we’ll leverage our looping techniques.
我们应该对两个数据集都执行此操作,因此我们将利用我们的循环技术。
There’s a lot going on above, so we’ll slowly break it down.
上面有很多事情,所以我们将慢慢分解。
We loop throughdatasets
to ensure we transform both of the beer and breweries data.Then, we create a new key calleddata_as_dicts
mapped to an empty array which will hold our new dictionaries.Then we start iterating over all the data, contained in thedata
key.zip()
is a function that takes two or more lists and makes tuples based off these lists.We take advantage of thezip()
output and usedict()
to create new data in our preferred form: column names mapped to their actual value.Finally, we append it todata_as_dicts
list. The end result is better formatted data that is easier to read and come back to repeatedly. 我们遍历datasets
以确保我们同时转换啤酒和啤酒厂数据。 然后,我们创建一个名为data_as_dicts
的新键,该键映射到一个空数组,该数组将保存我们的新字典。 然后,我们开始遍历data
密钥中包含的所有data
。zip()
是一个函数,它接受两个或多个列表,并根据这些列表创建元组。 我们利用zip()
输出,并使用dict()
以我们喜欢的形式创建新数据:将列名映射到其实际值。 最后,我们将其附加到data_as_dicts
列表。 最终结果是格式更好的数据,该数据更易于读取并反复返回。
We can look at the end result below.
我们可以看下面的最终结果。
# The first data row in the beers data setdatasets["beer"]["data_as_dicts"][0]>>> {'': '0','abv': '0.05','brewery_id': '408','ibu': '','id': '1436','name': 'Pub Beer','ounces': '12.0','style': 'American Pale Lager'}# The first data row in its original formdatasets["beer"]["raw_data"][0]>>> ['0', '0.05', '408', '', '1436', 'Pub Beer', '12.0', 'American Pale Lager']
# The first data row in the beers data setdatasets["beer"]["data_as_dicts"][0]>>> {'': '0','abv': '0.05','brewery_id': '408','ibu': '','id': '1436','name': 'Pub Beer','ounces': '12.0','style': 'American Pale Lager'}# The first data row in its original formdatasets["beer"]["raw_data"][0]>>> ['0', '0.05', '408', '', '1436', 'Pub Beer', '12.0', 'American Pale Lager']
章节摘要 (Section summary)
In this section, we learned how to use dictionaries with thefor
loop. Using loops, we reformatted each data row into dictionaries for enhanced readability. Our future selves will thank us later when we look back at the code we’ve written. We’re now set up to perform our final operation: matching all the beers to their respective breweries.
在本节中,我们学习了如何在for
循环中使用字典。 使用循环,我们将每个数据行重新格式化为字典,以提高可读性。 以后,当我们回顾所编写的代码时,我们将来的感谢。 现在,我们开始执行最终操作:将所有啤酒与各自的啤酒厂匹配。
Each of the beers has a brewery that it originates from, given by thebrewery_id
key in both data sets. We will create a whole new data set that matches all the beers to their brewery. We could use loops to accomplish this, but we have access to an advanced dictionary operation that could turn this data transformation from a multi-line loop to a single line of code.
每个啤酒都有一个啤酒厂,由两个数据集中的brewery_id
键指定。 我们将创建一个全新的数据集,将所有啤酒与其啤酒厂进行匹配。 我们可以使用循环来完成此操作,但是我们可以访问高级词典操作,该操作可以将数据转换从多行循环转换为单行代码。
字典理解 (Dictionary comprehensions)
Each beer in thebeers
data set was associated with abrewery_id
, which is linked to a single brewery inbreweries
. Using this ID, we can pair up all of the beers with their brewery. It’s generally a better idea to transform the raw data and place it in a new variable, rather than alter the raw data itself. Thus, we’ll create another dictionary withindatasets
to hold our pairing. In this new dicitonary, the brewery name itself is the key, the mapped value will be a list containing the names of all of the beers the brewery offers, and we will match them based on thebrewery_id
data element.
在每个啤酒beers
的数据集与一个相关联的brewery_id
,其被连接到在单个啤酒厂breweries
。 使用此ID,我们可以将所有啤酒与其啤酒厂配对。 通常,最好是转换原始数据并将其放置在新变量中,而不是更改原始数据本身。 因此,我们将在datasets
创建另一个字典来保存我们的配对。 在这个新的数字中,啤酒厂名称本身是关键,映射值将是一个包含啤酒厂提供的所有啤酒名称的列表,我们将根据brewery_id
数据元素将它们匹配。
We can perform this matching just fine with the looping techniques we learned previously, but there still remains one last dictionary aspect to teach. Instead of a loop, we can perform the matching succinctly usingdictionary comprehension. A “comprehension” in computer science terms means to perform some task or function on all items of a collection (like a list). A dictionary comprehension is similar to a list comprehension in terms of syntax, but instead creates dictionaries from a base list. If you need a refresher on list comprehensions, you can check out this tutorial here.
我们可以使用我们先前学到的循环技术很好地执行此匹配,但是仍然需要学习最后一个字典方面。 除了使用循环,我们还可以使用dictionary comprehension简洁地执行匹配。 计算机科学术语中的“理解”是指对集合的所有项目(例如列表)执行某些任务或功能。 字典理解在语法上类似于列表理解,但是从基本列表创建字典。 如果您需要复习列表知识,可以在此处查看本教程 。
To give a quick example, we’ll use a dictionary comprehension to create a dictionary from a list of numbers.
举个简单的例子,我们将使用字典理解来从数字列表中创建字典。
We will dissect the dictionary comprehension code below:
我们将在下面剖析字典理解代码:
To create a dictionary comprehension, we wrap 3 elements around an opening and closing bracket:
为了创建字典理解,我们将3个元素包裹在一个左,右括号中:
A base listWhat the key should be for each item from the base listWhat the value should be for each item from the base list 基本清单 基本列表中每个项目的键应该是什么 基本列表中每个项目的值应该是多少
nums
forms the base list that the key-value pairs ofdict_comprehension
are based off of. The keys are stringified versions of each number (to differentiate it from list indexing), while the values are a string describing what the key is. This pet example is useless by itself, but serves to illustrate the somewhat complicated syntax of a dictionary comprehension.
nums
是dict_comprehension
的键值对所基于的基本列表。 键是每个数字的字符串化版本(以区别于列表索引),而值是描述键是什么的字符串。 这个小例子本身是没有用的,但是可以用来说明字典理解的语法有些复杂。
Now that we know how a dictionary comprehension is composed, we will see its real utility when we apply it to our beer and breweries data set.
现在,我们知道词典理解是如何构成的,当将其应用于啤酒和啤酒厂数据集时,我们将看到其真正的效用。
We only need a two aspects of the breweries data set to perform the matching:
我们只需要啤酒厂数据集的两个方面来执行匹配:
The brewery nameThe brewery ID 啤酒厂名称 啤酒厂ID
To start off, we’ll create a list of tuples containing the name and ID for each brewery. Thanks to the reformatted data in thedata_as_dicts
key, this code is easy to write in a list comprehension.
首先,我们将创建一个元组列表,其中包含每个啤酒厂的名称和ID。 多亏了data_as_dicts
键中重新格式化的数据,该代码很容易以列表data_as_dicts
方式编写。
# This list comprehension captures all of the brewery IDs and names from storebrewery_id_name_pairs = [(row["brewery_id"], row["name"]) for row in datasets["breweries"]["data_as_dicts"]]
# This list comprehension captures all of the brewery IDs and names from storebrewery_id_name_pairs = [(row["brewery_id"], row["name"]) for row in datasets["breweries"]["data_as_dicts"]]
brewery_id_name_pairs
is now a list of tuples and will form the base list of the dictionary comprehension. With this base list, we will use to the name of the brewery name as our key and a list comprehension as the value.
brewery_id_name_pairs
现在是一个元组列表,并将构成字典理解的基本列表。 使用此基本列表,我们将使用啤酒厂名称作为键,并使用列表理解作为值。
Before we discuss how this monster works, it’s worth taking some time to see what the actual result is.
在讨论这个怪物的工作原理之前,值得花一些时间来看看实际结果是什么。
# Confirming that a dictionary comprehension creates a dictionarytype(brewery_to_beers)>>> <class 'dict'># Let's see what the Angry Orchard Cider Company (a personal favorite) makesbrewery_to_beers["Angry Orchard Cider Company"]>>> ["Angry Orchard Apple Ginger", "Angry Orchard Crisp Apple", "Angry Orchard Crisp Apple"]
# Confirming that a dictionary comprehension creates a dictionarytype(brewery_to_beers)>>> <class 'dict'># Let's see what the Angry Orchard Cider Company (a personal favorite) makesbrewery_to_beers["Angry Orchard Cider Company"]>>> ["Angry Orchard Apple Ginger", "Angry Orchard Crisp Apple", "Angry Orchard Crisp Apple"]
As we did with the simple example, we will highlight the crucial parts of this unwieldy (albeit interesting) dictionary comprehension.
正如我们在简单示例中所做的那样,我们将重点介绍这种笨拙(尽管很有趣)的字典理解的关键部分。
If we break apart the code and highlight the specific parts, the structure behind the code becomes more clear. The key is taken from the appropriate part of thebrewery_id_name_pair
. It is the mapped value that takes up most of the logic here. The value is a list comprehension with conditional logic. In plain English, the list comprehension will store any beers from the beer data when the beer’s associatedbrewery_id
matches the current brewery in the iteration.
如果我们分开代码并突出显示特定部分,则代码背后的结构会更加清晰。 密钥取自brewery_id_name_pair
的相应部分。 映射值占据了这里的大部分逻辑。 该值是具有条件逻辑的列表理解。 用简单的英语来说,当啤酒的关联brewery_id
与迭代中的当前啤酒厂匹配时,列表brewery_id
将存储啤酒数据中的所有啤酒。
Another illustration below lays out the code for the list comprehension by its purpose.
下面的另一个插图按其目的列出了列表理解的代码。
Since we based the dictionary comprehension off of a list of all the breweries, the end result is what we wanted: a new dictionary that maps brewery names to all the beers that it sells! Now, we can just consultbrewery_to_beers
when we arrive at a brewery and find out instantly what they have!
由于我们基于所有啤酒厂的列表来建立字典理解功能,因此最终的结果就是我们想要的:一个新的词典,它将啤酒厂名称映射到它所出售的所有啤酒! 现在,当我们到达啤酒厂时,我们只需要咨询brewery_to_beers
并立即发现他们拥有什么!
This section had some complicated code, but it’s wholly within your grasp. If you’re still having trouble, keep reviewing the syntax and try to make your own dicitonary comprehensions. Before long, you’ll have them in your coding arsenal.
本节有一些复杂的代码,但是完全由您掌握。 如果仍然有问题,请继续检查语法并尝试进行自己的数字理解。 不久,您将把它们放入编码库中。
We’ve covered a lot of ground on how to use dictionaries in this tutorial, but it’s important to take a step back and look at why we might want to use (or not use) them.
在本教程中,我们已经对如何使用字典进行了很多介绍,但是重要的是退后一步,看看为什么我们可能要使用(或不使用)它们。
词典的优缺点 (Dictionary Advantages and Disadvantages)
We’ve mentioned many times throughout that dictionaries increase the readability of our code. Being able to write out our own keys gives us flexibility and adds a layer of self-documentation. The less time it takes to understand what your code is doing, the easier it is to understand and debug and the faster you can implement your analyses.
在整篇文章中,我们多次提到字典增加了代码的可读性。 能够写出自己的密钥为我们提供了灵活性,并增加了一层自我文档。 理解代码所花费的时间越少,理解和调试就越容易,并且实现分析的速度就越快。
Aside from the human-centered advantages, there are also speed advantages. Looking up a key in a dictionary is fast. Computer scientists can measure how long a computer task (ie looking up a key or running an algorithm) will take by seeing how many operations it will take to finish. They describe these times with Big-O notation.
除了以人为本的优势之外,还有速度优势。 在字典中查找键很快。 计算机科学家可以通过查看完成一项任务需要多少时间来衡量计算机任务(即查找密钥或运行算法)需要花费的时间。 他们用Big-O表示法描述这些时间。
Some tasks are fast and are done in constant time while more hefty tasks may require an exponential amount of operations and are done in polynomial time. In this case, looking up a key is done in constant time. Compare this to searching for the same item in a large list. The computer must look through each item in the list, so the time taken will scale with the length of the list. We call this linear time. If your list is exceptionally large, then looking for one item will takemuchlonger than just assigning it to a key-value pair in a dictionary and looking for the key.
有些任务速度很快并且可以在恒定时间内完成,而较繁重的任务可能需要指数级的运算,并且需要多项式时间才能完成。 在这种情况下,查找密钥的时间是固定的。 将此与在大列表中搜索相同项目进行比较。 计算机必须浏览列表中的每个项目,因此花费的时间将与列表的长度成比例。 我们称此为线性时间。 如果您的列表非常大,那么查找一项要比将其分配给字典中的键值对并查找键所花的时间要长得多。
On a deeper level, a dictionary is an implementation of ahash table, an explanation of which is outside the scope of this article. What’s important to know is that the benefits we dictionary are essentially the benefits of the hash table itself: speedy key look ups and membership checks.
在更深层次上,字典是哈希表的实现,其解释超出了本文的范围。 重要的是要知道,我们词典的好处本质上就是哈希表本身的好处:快速的键查找和成员资格检查。
We mentioned earlier that dictionaries are unordered, making them unsuitable data structures for data where order matters. Relative to other Python data structures, dictionaries take up a lot more space, especially when you have a large amount of keys. Given how cheap memory is, this disadvantage doesn’t usually make itself apparent, but it’s good to know about the overhead produced by dictionaries.
前面我们提到过,字典是无序的,这使它们不适合用于顺序重要的数据的数据结构。 相对于其他Python数据结构,字典会占用更多空间,尤其是当您有大量键时。 考虑到便宜的内存是多少,这种缺点通常不会很明显,但是很高兴知道字典产生的开销。
We’ve only discussed vanilla dictionaries, but there are other implementations in Python that add additional functionality. I’ve included a link for further reading at the end. I hope that after reading this article, you will be more comfortable using dictionaries and finding use for them in your own programming. Perhaps you have even found a beer you might want to try in the future!
我们仅讨论了普通字典,但是Python中还有其他实现可添加其他功能。 最后,我提供了一个链接供进一步阅读。 我希望阅读完本文后,您会更习惯使用字典并在自己的程序中找到对它们的使用。 也许您甚至找到了将来可能要尝试的啤酒!
进一步阅读 (Further Reading)
We’ve covered the basics of dictionaries, but we didn’t cover all the methods available to us.
我们已经介绍了字典的基础知识,但是并未涵盖所有可用的方法。
Python’s Dictionary DocumentationPython Dictionaries are hash table implementationsEnhanced dictionaries in PythonError Handling in Python Python的字典文档 Python字典是哈希表实现 Python中的增强词典 Python中的错误处理
翻译自: //10/python-dictionary-tutorial/
python字典包含字典
如果觉得《python字典包含字典_Python字典教学》对你有帮助,请点赞、收藏,并留下你的观点哦!