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})}