Python学习笔记(2)之元组、字典&集合

0.写在前面

快开学了琐事比较多,就更新的慢了一些。开学以后也会边学边写,不定时更新,灰常感谢大家的支持和鼓励!也希望大佬们不吝赐教,多提提意见or建议,有什么好的学习资源的话也希望能分享一下,感激不尽!

这篇文章第一版中字典的BIF部分还没写完,我会尽快写完补上,因为刚刚被小伙伴提醒发现自己的wiki还没有写。。。

1. 元组(tuple)——一个上了锁的列表

“一切有权力的人都容易滥用权利。“ ——孟德斯鸠

在学完列表之后,发现列表真的是很强大。这种极大的灵活性无疑带来了很多便利,但是站在安全的角度上讲, 却不利于保护数据。于是元组应运而生。

元组是一种不可改变的类型,一旦定义了元组,里面的任何一个元素都无法再更改。元组(tuple)和列表(list)在使用上十分相似,因此我只是简记一下它们不同之处。关于列表的相关内容可参见文末的上一篇文章。

1.1 建立元组

在建立列表时,只需要中括号[ ]来创建。对应的,建立元组一般只需用小括号( )即可,元素之间用逗号分隔。

>>> tuple1 = (1 , '嘻嘻嘻' , [1,2,3] , int)
>>> type(tuple1)
<class 'tuple'>

注意!小括号( )不是元组的特征,逗号才是!!

>>> temp = ( 1 )
>>> type(temp)
<class 'int'>

会发现,即使加上了小括号,temp仍然是整型!

>>> temp = 1 , int , '嘻嘻嘻' , int
>>> type(temp)
<class 'tuple'>

因此,逗号才是元组的标志!However,中括号[]确是list的标志!

>>> temp = [ 1 ]
>>> type(temp)
<class 'list'>

不过用小括号创建空元组是可行的。

>>> temp = ()
>>> type(temp)
<class 'tuple'>

那么问题来了,要建立只有一个元素的元组怎么办呢?可以这样:

>>> temp = (1,)

>>> type(temp)
<class 'tuple'>
>>> len(temp)
1

甚至可以进一步简化为

>>> temp = 1,
>>> type(temp)
<class 'tuple'>

1.2 元组切片(slice)

这部分元组和列表是完全一样的,因此不多赘述。Python处理元组仍然是“贴标签”的方式。

>>> tuple1 = (1 , '嘻嘻嘻' , [1,2,3] , int)

>>> tuple1[3]
<class 'int'>

>>> tuple1[2:]
([1, 2, 3], <class 'int'>)

>>> tuple2 = tuple1[:]   #copy a tuple
>>> print(tuple2)
(1, '嘻嘻嘻', [1, 2, 3], <class 'int'>)

1.3 元组不可添加、删除、修改元素

若按列表的方式去试图修改元组会报错。

>>> tuple1 = (1 , '嘻嘻嘻' , [1,2,3] , int)

>>> tuple1.append('可以添加吗?')
Traceback (most recent call last):
  File "<pyshell#30>", line 1, in <module>
    tuple1.append('可以添加吗?')
AttributeError: 'tuple' object has no attribute 'append'
    
>>> tuple1[1] = '可以修改吗?'
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    tuple1[1] = '可以修改吗?'
TypeError: 'tuple' object does not support item assignment

1.4 操作符&比较大小

这部分和列表是完全相同的,+,*,in等操作符可用于元组,元组之间可比较大小,比较的方法和列表相同。

>>> temp = 1 , 2

>>> temp * 3
(1, 2, 1, 2, 1, 2)

>>> 1 in temp
True
Tips: 变相"修改"元组中元素
>>> tuple1 = (1 , '嘻嘻嘻' , [1,2,3] , int)
>>> tuple1 = tuple1[:2] + ('加一个元素',) + tuple1[2:]
>>> print(tuple1)
(1, '嘻嘻嘻', '加一个元素', [1, 2, 3], <class 'int'>)

这样,我们就在tuple1里加了一个元素进去。这是怎么做到的呢?事实上,只是巧妙的运用了元组的拼接。看似是tuple1中多了一个元素,其实是我们创建了一个新的元组,再把tuple1这个标签贴到了新元组上而已。类似地,可用切片间接地“删除”元组里的元素。

无论如何元组是不可改变的!

也可以利用函数list()将元组转换成列表,再对其进行修改。

2. 字典 (dictionary)—— A kind of mapping

列表中的元素是有序的,并且有属于自己的索引值。调取列表中的元素只能通过其索引值来实现。而“字典”提供了一种key+value的方式,给每个元素一个标签,这样我们便可以通过该表现来调取元素。

2.1 创建字典

创建字典最简单的方式是用大括号{ },格式为{key1: value1 , key2: value2 , ...},调取时直接通过object[key]的方式。

>>> dict1 = {'目标':'减肥!减肥!' , '口号':'燃烧我的卡路里!'}
>>> print('我们的口号是:' + dict1['口号'])
我们的口号是:燃烧我的卡路里!
利用dict()函数

dict()函数有两种用法,一种是dict(mapping),其中mapping可以用元组或着列表的形式给出。

>>> dict1 = dict((('目标','减肥!减肥!') , ('口号','燃烧我的卡路里!')))
>>> print(dict1)
{'目标': '减肥!减肥!', '口号': '燃烧我的卡路里!'}

hhh看上去好多括号,主要原因是用这种方式的话dict只能有一个参数,所以必须用()或者[]给括起来喏。

另一种方式是用关键字参数dect(key1=value1, key2=value2, ...),注意key是不能加引号的!

>>> dict2 = dict(目标='减肥!减肥!' , 口号='燃烧我的卡路里!')
>>> print(dict2)
{'目标': '减肥!减肥!', '口号': '燃烧我的卡路里!'}

2.2 常用操作

在字典中添加元素可以直接采用object[a new key]=value的方式。

>>> dict2['方式'] = '每天跑步十公里!'
>>> dict2
{'目标': '减肥!减肥!', '口号': '燃烧我的卡路里!', '方式': '每天跑步十公里!'}

删除元素的话采用del object[key]的方式即可。

>>> dict2 = {'目标': '减肥!减肥!', '口号': '燃烧我的卡路里!', '方式': '每天跑步十公里!'}
>>> del dict2['目标']
>>> dict2
{'口号': '燃烧我的卡路里!', '方式': '每天跑步十公里!'}

2.3 常用的BIF

占个位置先,日后补上。。。

3. 集合(set)

Python中的集合和数学中的集合的性质是相同的,即无序性和互异性。

3.1 建立集合

创立集合也有两种方式。一是用大括号{},当大括号里只有value而没有key时,所创建的数据类型即为集合。

>>> set1 = {1 , 2 , int , '嘻嘻嘻'}
>>> type(set1)
<class 'set'>

另一种方式是利用set()函数,将列表或元组转换成集合。

>>> set([1 , 1 , 2 , '嘻嘻嘻' , int])
{1, 2, '嘻嘻嘻', <class 'int'>}

有趣的是,原来列表中的两个"1"变成集合后只剩一个了。

问:如何删除列表中重复的值?

>>> num1 = [1,2,3,4,5,4,3,2,1]
>>> num1 = list(set(num1))
>>> print(num1)
[1, 2, 3, 4, 5]

3.2 访问集合中的值

集合中的元素是无序的,因此若试图通过索引值来访问集合中的值会报错。

>>> set1 = {1 , 2 , int , '嘻嘻嘻'}

>>> set1[1]
Traceback (most recent call last):
  File "<pyshell#85>", line 1, in <module>
    set1[1]
TypeError: 'set' object does not support indexing

可以利用for循环来读取集合中的值,举个简单的例子:

>>> set1 = {1 , 2 , int , '嘻嘻嘻'}
>>> for i in set1:
         print(i , end=' ')

1 2 嘻嘻嘻 <class 'int'> 

3.3 集合的运算

设A、B是两个集合,则集合的运算可以通过以下方式进行:

运算符 意义
A <= B 子集测试 :A 是B的子集
A < B 子集测试 :A 是B的真子集
A >= B 超集测试 :B 中所有的元素都是 A 的成员
A > B 等价于 B < A
A | B 取并集
A & B 取交集
A - B 差分操作:在 A 中存在,在 B 中不存在的元素
A ^ B 对称差分操作:A "或" B 中的元素,但不是 A 和 B 共有的元素

例如

>>> a={1,2,3}
>>> b={1,3,4}
>>> c={1,2,3,4}

>>> a & b
{1, 3}

>>> a | b
{1, 2, 3, 4}

>>> a - b
{2}

>>> a<c
True

3.4 向集合中添加、删除元素

添加或删除集合中的元素可分别使用.add().remove()函数。

>>> set1 = {1 , 2 , int , '嘻嘻嘻'}
>>> set1.add(1e5)
>>> print(set1)
{100000.0, 1, 2, '嘻嘻嘻', <class 'int'>}
>>> set1.remove('嘻嘻嘻')
>>> print(set1)
{100000.0, 1, 2, <class 'int'>}

3.5 不可变集合(frozen set)

若想定义一个类似与元组一样不可变的集合,可以利用frozenset()函数。顾名思义,不可变集合的元素是无法进行修改的。

>>> set2 = frozenset([1 , int , '嘻嘻嘻'])
>>> set2.add(0)
Traceback (most recent call last):
  File "<pyshell#97>", line 1, in <module>
    set2.add(0)
AttributeError: 'frozenset' object has no attribute 'add'

3.6 关于可哈希(hashable)

如果一个对象在自己的生命周期中有一哈希值(hash value)是不可改变的,那么它就是可哈希的(hashable)的,因为这些数据结构内置了哈希值,每个可哈希的对象都内置了hash方法,所以可哈希的对象可以通过哈希值进行对比,也可以作为字典的键值和作为set函数的参数。所有python中所有不可改变的的对象(imutable objects)都是可哈希的,比如字符串,元组,也就是说可改变的容器如字典,列表不可哈希(unhashable)。我们用户所定义的类的实例对象默认是可哈希的(hashable),它们都是唯一的,而hash值也就是它们的id()。

简单来讲,Python中有些数据类型是不可变的,比如字符串str、元组tuple、对象集objects、不可变集合frozenset,称为可哈希(hashable)的数据类型;也有些数据类型是可变的,比如字典dict,列表list,集合set,称为不可哈希(unhashable)的数据类型。

集合和字典的存储方式都是保存元素的哈希值,因此集合和字典都是无序的,并且集合中哈希值相同的元素(相同元素)便保存为一个,这也便是集合的互异性(或者叫唯一性)。因此,集合无法储存不可哈希的数据类型。举个例子:

>>> { [1,2] , int , '嘻嘻嘻'}
Traceback (most recent call last):
  File "<pyshell#105>", line 1, in <module>
    { [1,2] , int , '嘻嘻嘻'}
TypeError: unhashable type: 'list'

这样创建的集合会报错,提示列表list是不可哈希的。同样集合中的元素不能是集合,但是可以是不可变集合frozenset。

>>> set1 = set([1,2,3,4])        #创建一个集合
>>> set2 = frozenset([1,2,3,4])   #创建一个不可变集合


>>> {set1}
Traceback (most recent call last):
  File "<pyshell#111>", line 1, in <module>
    {set1}
TypeError: unhashable type: 'set'

>>> {set2}
{frozenset({1, 2, 3, 4})}

往期回顾

Python学习笔记(0)之Hello,python!
Python学习笔记(1)之列表list

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349