暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

是你认识的列表、字典、元组、集合吗?(上篇) - Python高手成长路(系列)(第1阶段)

好想学Python 2018-06-28
237

我是DJun(小丁),码龄18年,从事IT工作5年,踩过无数“语言”坑最后入坑Python,想通过公众号,把自己的成长经历与经验分享给朋友们。

同名酷安看看号“好想学Python”已开通,欢迎订阅。


本篇摘要

我们了解到Python不仅有整数、浮点数、布尔值、字符串等基本数据类型,还有列表、字典、元组、集合这些基本数据结构。初入门Python的朋友,或许会把“列表”理解为“数组”,或许只记住“字典”有“键”和“值”的对应关系,或许只知道“元组”相当于一个不可变的“列表”,或许只知道“集合”里面的元素都是不重复的,但是真正碰到题目(或者工作中的需求)的时候,却懵圈这“四大件”应该怎么应用起来。

本篇分上、下两篇,将在我们已经了解列表、字典、元组、集合的基本操作的基础上,着重深入对它们特点上的理解,之后在实际应用中可以信手拈来,耍得6666的(手动滑稽)。

文末会附上新的作业题,欢迎在留言区踊跃参与。

往期精选

>>> Python从哪里开始学好呢?

>>> 一道简单的程序题?


在讲“四大件”之前,我们先来明确一下对Python变量的理解。

Python的变量赋值跟大多数程序语言类似,一个等于号(=),左边变量名,右边是被赋值的数据。需要注意的是,Python的变量保存的是对数据的“引用”,这类似Java,new一个对象给某个变量名,那么这个变量便有了这个新对象的“引用”。

换种说法来说,Python的变量它保存的是一个指向内存某块区域的ID,变量本身不是一个容器。直接print变量只能输出变量对应的数据内容,我们可以改为用id()函数来验证变量保存内存引用这一点。id()这个函数用于获取对象的内存地址。

我们先尝试一下基本数据类型int(整数)和str(字符串)。

我们对a、b分别操作赋值1,赋值操作后,实际上a跟b都指向同个内存区域,这个区域储存了“1”这个数据。

我们对d、e分别操作赋值'a',赋值操作后,实际上d跟e都指向同个内存区域,这个区域储存了“a”这个数据。

我们再尝试一下基本数据结构类型list(列表)。dict(字典)、tuple(元组)、set(集合)同理,此处不作测试,朋友们可以自己尝试看看。

我们对g、h分别操作赋值“[]”(表示空列表的构造,跟调用list()返回的一致,得到的就是一个空的list),赋值操作后,实际上g跟h都指向不!同!的!内存区域,分别储存了两个空的list。

那为什么“g==h”返回True,而“g is h”返回却是False呢?

划重点!Python这里的“==”判断就跟Java不一样了,Python的是判断“内容”是否一致;而Java判断的是变量保存的内存“引用”地址是否一致,相当于Python里的“is”。在这个例子里,显然两个空list“内容”一致,都是空的,所以“g==h”是True;而两个空list的id值不一样,当然“g is h”就是False了。

回到我们刚才测试基本数据类型int时的a和b这两个变量,“a==b”和“a is b”理所当然地都是True,毕竟值一致,id也一致。


01

列表与“切片”


列表是一种容器序列,可以简单理解为按索引顺序(0、1、2、3……)保存变量的一种数据结构类型。通过“[]”、“list()”可以迅速创建一个空列表来使用。

“列表”跟“数组”不一样的地方在于,它保存的每个元素可以是任意对象的引用(包括列表它自己!),而“数组”的所有元素只能保存同一基本数据类型的元素。Python有专门的“数组”类型“array”,通过import array来使用,篇幅关系此处暂时不深入。

“切片”是Python中设计的一种非常强大的数据处理操作方法,一句话来说,“切片”就是把有顺序的数据按一定规则“切”开来。列表、字符串、元组这几种序列类型都支持“切片”操作,需要留意的是“切片”是一种通用的操作方法,不能死记硬背“列表、字符串、元组”能切片,因为我们还可以通过“魔术方法”给自己定义的类增加实现切片的切口,比如操作Excel数据的第三方模块pyopenxl,它的sheet(工作表)对象也支持切片方法,这种切片对应的具体操作的是切出指定的Excel的单元格范围。“魔术方法”将会另起新篇进行详解。

我们回顾一下上一篇文章末尾留的作业题。这道题目可以直接体现“切片”操作带来的巨大便利性。

(题目补充:输入输出的例子漏了写是n=2的情况)

酷友 @tongyuantongyu 提供了一个用列表“切片”来做的代码答案,如图。

思路是这样的:

① 输入要处理的字符串a,右移位数b;

② 取字符串a的从索引b开始的位置至末尾,拼接取字符串开头至索引b的前一位;

也就是说,根据这段代码,输入的字符串a='abcdefghi',此时输入b=2,即字符串a右移两位,通过“切片”,把字符串最右边的“hi”切出来,接到同样也是切出来的“abcdefg”的左边,即可完成右移2位的操作。

对比一下,如果是使用Python以外的不带“切片”操作的语言,如C语言,需要另外考虑一下字符串指针相关操作,而这些在Python的包装设计下都隐藏起来了,我们只需要关注在具体问题上,考虑如何用现成便利的东西最迅速地解决问题。这也是Python相比其他语言“简单”“容易”的原因之一,并不是它简单得很难解决问题,而是简单地快速解决问题!

但是提醒一下,图上这段代码有一个不明显的Bug,当代码中代表右移位数的b大于字符串a的长度时,“切片”操作就无法正确处理题目中的“循环右移”的需求了,比如a='abcdefghi'、b=99,输出结果却是跟字符串a一样的字符串'abcdefghi',这是不正确的。考虑到当b等于字符串a的长度时,输出结果就刚好是跟字符串a一样的值,只要在第2行代码最后加一个“%”(求余)操作就可以解决问题了。另代码第3行的“a[b:] + a[:b]”应修改为“a[-b:] + a[:-b]”。此处留给朋友们自己尝试练习哈。


02

字典与“映射关系”


我们已经知道,字典可以保存“映射关系”,有整数或字符串作“key”(键),对应值作“value”(值)。事实上,这里的“值”也是保存“引用”,因此简单来说,字典是保存“键”与“引用”对应关系的一种数据结构类型。请留意,它不是序列类型,并没有记忆键值对的排列顺序。

字典在增、删、改、查数据的时候,也并不是像有记忆顺序的“列表”一样,一个一个“键”地找来把对应的“值”找出来的。字典之所以称之为“字典”,是因为它像实物字典一样,翻看目录寻找对应关系(词条对应的页数),把词条对应的解释翻出来,在Python这里,“键”就是“词条”,用它可以直接查到对应的“词条解释”,也就是字典的“值”。

字典是一种容器,增、删、改、查效率非常高,得益于底层是“哈希表”数据结构的实现,简单理解,它是通过对“键”进行一系列的数值计算转换变成内存地址,直接从该内存地址取出对应的“值”。由于这个对“键”的转换过程是“计算”出来的,要尽量避免计算结果重复导致不同的“键”指向同个“值”,因此才要求“键”必须是int类型或者str类型,这样不仅便于“计算”,而且计算结果重复率也可以通过算法优化尽量降到最低。

实际应用时,我们并不需要去记忆它的原理,只需要知道它“快”,它有“映射关系”,就可以了。同时也要再次留意,它不像列表一样有记忆排列顺序,也就是说先加入字典的键值对,并不一定排在后加入的键值对的前面。

举一个经典简单的字典应用例子,加密解密。

· (例子) 现在有一种加密方式,它可以把数字0至9根据加密表加密为另一串数字,加密表如下。

  0 → 5  |  5 → 1

  1 → 9  |  6 → 0

  2 → 4  |  7 → 3

  3 → 7  |  8 → 2

  4 → 8  |  9 → 6

  根据这个加密表,对输入的一串数字进行加密。

  输入:一串数字(例如 0204788)

  输出:一串加密后的数字(加密后为 5458322)

在这个例子中,很明显地看到有“对应关系”的需求,这时候Python字典就可以派上用场了。

使用题目的例子输入“0204788”测试,具体如下。

代码答案中,定义一个带有这种加密对应关系的字典encoder,就可以简单完美地解决问题。

我们再对比一下Java的字典(哈希表)定义形式:

这段Java代码比较罗嗦,并没有写完整。虽然Java中可以自己分别定义“键”、“值”的数据类型,但相比之下,Python考虑到最为常用的字典形式是键为int或str类型,而且能通过自带模块json进行序列化,因此优化为可以用这种“{}”号的形式快速初始化一个带有对应关系的字典,非常方便。


列表、字典在上篇就介绍到这里。元组、集合,将在下篇与朋友们继续深入理解。下篇见~


· (作业题) 自己设计一个针对数字0到9、大写字母A到Z组成字符串的加密解密器,要求加密后也同为数字0到9、大写字母A到Z组成的字符串,加密后字符串与加密前每位完全不相同,且再进行解密时能正确被解密成原来的字符串。

输入:先输入选择加密还是解密的操作,然后输入一个字符串

输出:输出加密或解密后的字符串



希望本篇可以给感兴趣或者想要学习的朋友们带来帮助哈。 

有其他疑问也请在下方留言提出,会尽力解答~


文章转载自好想学Python,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论