目录
一、建立一个数据火车——列表
1、创建列表
2、列表元素的获取
3、列表元素的添加
4、列表元素的删除
5、列表元素的修改
二、列表的亲兄弟——元组
1、创建元组
2、元组元素的获取
3、元组和列表的差别
三、数据中的魔术师——字符串
1、创建字符串
2、字符的获取
3、字符串的处理
4、字符转义
5、原始字符串
6、多行字符串
7、列表、元组、字符串的通用操作
8、列表、元组、字符串总结
四、索引存储不再麻烦——字典
1、创建字典
2、字典键值对的添加
3、键值对的获取
4、字典键值对的删除
5、字典中键值对修改
6、什么时候用字典
五、比较专一的大火车——集合
1、创建集合
2、集合元素的添加
3、集合元素的获取
4、集合元素的删除
5、集合的运算
6、集合运算示例
7、什么时候用集合
8、获取字典和集合中的元素数量
9、字典和集合大总结
写在最后
Hello,你好呀,我是灰小猿,一个超会写bug的程序猿!
近期和大家分享总结了关于Python基础进阶的文章“【全网力荐】堪称最易学的Python基础入门教程”,然后得到了很多小伙伴的支持和肯定,但是同时很多刚开始学习的小伙伴在编程的时候还会遇见很多错误,所以就又为大家总结了一篇关于Python常见报错及其解决方案的文章“全网最值得收藏的Python常见报错及其解决方案,再也不用担心遇到BUG了!”。来帮助大家解决在前期学习中遇到的一些bug。感兴趣的小伙伴可以去阅读一下。
之后还会计划和大家分享更多的Python基础及进阶技术,大家可以关注我一起进步呀!
今天就继续来和大家分享Python基础入门之后的又一技术:列表、元组、字符串处理、字典和集合类型。文章较长,建议先收藏之后慢慢学习!
可能很多小伙伴在其他的编程语言中也见过这几个类型的使用,但是在Python对其的学习绝对会让你不虚此读!!!
我们之前学习了字符串和列表,除此之外 Python 中还内置有元组、字典、集合等常用的数据类型,它们都被用于存放批量数据。
存放批量数据用列表不就行了吗,为什么还要这么多数据类型?这是因为在不同的场景下,对数据的读取和修改效率以及内存使用情况的要求是不一样的,为了满足不同的场景需求,需要以不同的组织形式来存放数据。上面所述的那些数据类型,本质上就是不同的数据组织形式,Python 直接为我们提供了它们的现成的实现,我们拿来即可使用,轻而易举地获取各种不同的存放、访问和修改数据的能力。
列表、元祖、字典、集合、字符串这些数据类型中所存放的一个个单独的数据,叫作项(Item)或元素(Element)。这些数据类型除了可以存放元素以外,还能通过调用对象方法来操作管理其中的元素。
我们来详细学习下这五种内置数据类型。
列表是 Python 中非常常用的数据类型。之前的章节中我们学习过列表的一些基础知识,这个小节将会更深入地介绍列表的各种功能。
列表是用于存放若干元素的有序序列。列表使用方括号([]
)来表示,其中的元素写入方括号中,多个元素时用逗号分隔,如 [1, 'go', [0.1, 0.2]]
。它的元素可以是任意数据类型,甚至也可以是个列表。
元素之间有顺序关系,每个元素都有自己的位置,每个位置从 0 开始依次标号,这个表示位置的数字叫作索引。
列表被创建之后,我们可以对它做很多操作,包括添加元素,删除元素,修改元素,查找元素等。
创建空的列表:
列表 = []
>>> items = []
>>> items
[]
创建包含元素的列表:
列表 = [元素1, 元素2, ..., 元素N]
>>> items = [1, 2, 3]
>>> items
[1, 2, 3]
通过索引获取元素
元素 = 列表[索引]
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters[2]
’c’
通过元素获取索引
这种方式和上面相反,首先在列表中寻找元素,然后返回元素对应的索引。
索引 = 列表.index(元素)
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.index(‘c’)
2
查看元素是否存在于列表中
要想查看元素是否存在于列表中,需要借助 Python 的关键字 in
,使用如下:
布尔值 = 元素 in 列表
>>> letters = [‘a’, ‘b’, ‘c’]
>>> ‘a’ in letters
True
>>> ‘z’ in letters
False
统计元素在列表中的个数
统计元素在列表中的个数,或者说是元素在列表中出现的次数。
个数 = 列表.count(元素)
>>> numbers = [1, 2, 2, 3, 4, 5, 5, 7]
>>> numbers.count(5)
2
我们可以很灵活地向列表添加元素,如以追加的形式向列表末尾添加一个元素;以插入的形式向列表的任意位置插入元素;或者将一个列表中的所有元素批量的添加到另一个列表中。
向列表末尾追加元素
列表.append(元素)
>>> letters = [‘a’, ‘b’]
>>> letters.append(‘c’)
>>> letters
[‘a’, ‘b’, ‘c’]
向列表的任意位置插入元素
列表.insert(索引, 元素)
>>> letters = [‘a’, ‘b’]
>>> letters.insert(0, ‘c’)
>>> letters
[‘c’, ‘a’, ‘b’]>>> letters.insert(2, ‘d’)
>>> letters
[‘c’, ‘a’, ‘d’, ‘b’]
列表末尾追加另一个列表的所有元素
列表.extend(另一列表)
>>> letters = [‘a’, ‘b’]
>>> letters.extend([‘c’, ‘d’, ‘e’])
>>> letters
[‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
删除元素的方式同样很灵活。
按索引删除元素
元素 = 列表.pop(索引)
pop(索引)
会将索引对应的元素从列表中删除,同时返回这个元素。
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.pop(0)
’a’
>>> letters
[‘b’, ‘c’]
也可以不传递索引,这样的话默认删除并返回最后一个元素。
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.pop()
’c’
>>> letters
[‘a’, ‘b’]
按索引删除元素(del
方法)
删除一个列表元素也可以使用 Python 中的 del
关键字,如下:
del 列表[索引]
>>> letters = [‘a’, ‘b’, ‘c’]
>>> del letters[0]
>>> letters
[‘b’, ‘c’]
直接删除元素
直接删除元素时,Python 会先在列表中遍历该元素,然后将匹配到的第一个元素删除。
列表.remove(元素)
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.remove(‘b’)
>>> letters
[‘a’, ‘c’]
清空所有元素
清空所有元素即是把列表元素全部删除,最后仅为列表仅为 []
。
列表.clear()
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.clear()
>>> letters
[]
通过赋值修改列表元素
列表[索引] = 新元素
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters[2] = 'd’
>>> letters
[‘a’, ‘b’, ‘d’]
反转整个列表
反转整个列表会将所有的元素倒序排列。
列表.reverse()
>>> letters = [‘a’, ‘b’, ‘c’]
>>> letters.reverse()
>>> letters
[‘c’, ‘b’, ‘a’]
列表元素排序
列表.sort()
>>> numbers = [2, 4, 5, 2, 1, 5, 7, 3]
>>> numbers.sort()
>>> numbers
[1, 2, 2, 3, 4, 5, 5, 7]
也可以通过指定 sort
方法的 reverse
参数来倒序排列。
列表.sort(reverse=True)
>>> numbers = [2, 4, 5, 2, 1, 5, 7, 3]
>>> numbers.sort(reverse=True)
>>> numbers
[7, 5, 5, 4, 3, 2, 2, 1]
元组和列表非常相似,也是用于存放元素的有序序列。它用的圆括号(()
)表示,元素写入圆括号中,多个元素时用逗号分隔,如 (1, 2, 3)
。
元组同样具有索引,索引使用方式与列表一致。其元素同样可以是任意类型。
看起来元组就是披着圆括号外衣的列表嘛!有什么区别?
元组创建完成后,便不能向其中添加元素,也不能修改和删除其中的任何一个元素。所以它与列表相比,只能查找元素,也就是说只具备读的功能,不具备写的功能。元组的这一特性叫作不可变(性)(Immutable),而列表是可变的(Mutable)。
创建空的元组:
元组 = ()
>>> items = ()
>>> items
()
创建包含多个元素的元组:
元组 = (元素1, 元素2, ..., 元素N)
>>> items = (1, 2, 3)
>>> items
(1, 2, 3)
创建只包含一个元素的元组
只包含一个元素的情况需要单独说明一下,因为它的形式与直觉不相符。
创建只包含一个元素的元组,需要在唯一的那个元素后面加上逗号,如:
元组 = (元素,)
>>> items = (1,)
>>> items
(1,)
这是因为,如果括号中只有一个元素,那么 Python 会将这个括号当作优先级符号进行处理(像数学中的那样),而不是当作元组。可以试一下:
>>> items = (1)
>>> items
1
>>> type(items)
<class ‘int’>
通过索引获取元素
元素 = 元组[索引]
>>> letters = (‘a’, ‘b’, ‘c’)
>>> letters[2]
’c’
通过元素获取索引
索引 = 元组.index(元素)
>>> letters = (‘a’, ‘b’, ‘c’)
>>> letters.index(‘c’)
2
查看元素是否存在于元组中
布尔值 = 元素 in 元组
>>> letters = (‘a’, ‘b’, ‘c’)
>>> ‘a’ in letters
True
>>> ‘z’ in letters
False
统计元素在元组中出现的个数
个数 = 元组.count(元素)
>>> numbers = (1, 2, 2, 3, 4, 5, 5, 7)
>>> numbers.count(5)
2
我们可以看到,元组所具有的操作在使用方式上与和列表非常相似,甚至在一定程度上可以将元组看作是列表的精简版,但它们之间也有明显的差别。
- 元组是不可变的(Immutable),列表是可变的(Mutable),元组在被创建之后,就不能添加、删除和修改元素,而列表可以
- 一般情况下元组的性能在略高于列表
我们在什么时候用列表,什么时候用元组?
列表还是元组,通常性能不是从它们中做选择的主要考虑因素,因为它们之间的性能差异不是很大。我们的选择通常围绕着可变和不可变的特性进行,当我们需要添加元素或修改元素时,使用列表;当我们希望所有元素在创建之后便不再改变,可使用元组。
字符串也是 Python 中非常常用的内置数据类型。我们之前学习过字符串的一些内容,现在来深入的了解下。
为什么要叫它是数据中的魔术师呢?原因是因为它可以转义成很多你想要的数据类型,接下来往下看你就知道了!
字符串是 Python 中用来存放字符序列的数据类型,其中的元素只能是字符。字符串使用单引号或双引号来表示,如 'pick'
,"cherry"
,通常我们首先使用单引号。
字符串是有序序列,可以使用索引来获取其中某个位置的元素。它是不可变的,被创建之后其中的元素(也就是字符)不能被修改和删除。
创建空字符串(即不包含字符的字符串):
字符串 = ''
>>> string = ''
>>> string
’’
创建包含元素的字符串:
字符串 = '若干字符'
>>> string = 'happy’
>>> string
’happy’
通过索引获取字符
字符 = 字符串[索引]
>>> string = ‘happy’
>>> string[2]
’p’
通过子串获取索引
所谓子串就是从字符串中截取下来的一部分,可以是一个字符,一部分字符、全部字符、或空字符串,如 'a'
、'ppy'
、'happy'
、''
都是 ‘happy’ 的子串。查找子串时,返回的是子串的第一个字符的索引。
索引 = 字符串.index(字符)
>>> string = ‘happy’
>>> string.index(‘p’)
2
>>> string = ‘happy’
>>> string.index(‘app’)
1
当字符或子串不存在时,index
方法将抛出 ValueError
错误。
也可采用字符串的 find
方法来查找子串,使用方式与 index
一致,不同点在于 find
方法未找到子串时返回数字 -1
,而不抛异常。
>>> string = ‘happy’
>>> string.find(‘app’)
1
>>> string.find(‘z’)
-1
查看字符是否存在于字符串中
查看字符是否存在于字符串中,需要借助 Python 的关键字 in
,如下:
布尔值 = 字符 in 字符串
>>> string = ‘happy’
>>> ‘a’ in string
True
>>> ‘z’ in string
False
统计字符在字符串中的个数
个数 = 字符串.count(字符)
>>> string = ‘happy’
>>> string.count(‘p’)
2
字符串自带的方法非常多,除了上面介绍的几个之外还有四十多个,这是因为字符处理是编程时的一项高频工作。Python 将这些字符处理相关的功能以方法的形式集成在字符串里。
这里列举几个常见的方法:
startswith:判断字符串是否以某个子串开头,返回布尔值
>>> string = ‘happy’
>>> string.startswith(‘ha’)
True
endswith:判断字符串是否以某个子串结尾,返回布尔值
>>> string = ‘happy’
>>> string.endswith(‘y’)
True
replace:将字符串的子串用一个另一个字符串替换,返回一个新的字符串
>>> string = ‘happy’
>>> string.replace(‘y’, ‘iness’)
’happiness’
strip:去除字符串前后的空白符号,如空格、换行符、制表符,返回一个新的字符串
>>> string = ’ \t happy \n’
>>> string.strip()
’happy’
split:将字符串用某个子串分隔开,分隔后的各个部分放入列表中,并返回这个列表
>>> string = ‘I am happy’
>>> string.split(’ ')
[‘I’, ‘am’, ‘happy’]
join:将一个序列中的元素用某个字符(串)拼接,组成一个大的字符串,并返回这个字符串
>>> words = [‘I’, ‘am’, ‘happy’]
>>> ’ '.join(words)
’I am happy’
upper:将字符串转化为大写字母形式,返回一个新的字符串
>>> string = ‘happy’
>>> string.upper()
’HAPPY’
lower:将字符串转化为小写字母形式,返回一个新的字符串
>>> string = ‘HAPPY’
>>> string.lower()
’happy’
注意上面的这些字符处理功能,对字符串作处理后都是返回一个新的字符串,而不会直接修改原有的字符串。为什么呢?字符串不可变呀!
我们在创建字符串时,有一些字符是没法直接在引号中表示的,如单引号或双引号,因为这和表示字符串本身的符号冲突了,如:
>>> string = 'I’m happy’
File “”, line 1
string = ‘I’m happy’
^
SyntaxError: invalid syntax
抛出 SyntaxError
语法错误异常,因为 Python 将 string = 'I'
看作字符串的赋值,而后面的 m happy'
就无法解析了,因为不符合任何语法。
这时就需要使用字符转义了,我们在这类无法直接在字符串中表示的字符前加上 \
符号,形如 \'
,这样 Python 在解析时就能理解这是嵌入在字符串中的单引号 '
:
>>> string = 'I\'m happy’
>>> string
"I’m happy"
像 \'
这样在前面加了反斜杠(\),为了能在字符串中正常表示的字符,叫作转义字符。而这个转化的行为叫作字符转义。
与单引号的用法相同,双引号用 \"
来转义。
字符串中的 \
用来做字符转义了,那怎么在字符串中表示斜杆 \
这个字符呢?使用 \\
,将斜杆 \
转义一下。除此之外,有一些空白符号也需要用转义字符来表示,因为我们没办法直接在字符串中表示它们,如常见的换行(\n
),制表符(\t
),回车(\r
)。
常用的转义字符 | 含义 |
---|---|
\' | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
\n | 换行符 |
\t | 制表符(Tab) |
\r | 回车 |
举个例子,如果在字符串使用了 \n
,那么在用 print()
输出字符串的时候,这个字符串会被换行输出。如:
>>> print(‘第一行\n第二行’)
第一行
第二行
使用 \n
换行符使得我们能够在一行的字符串来表示多行的内容。
说明:转义字符虽然在书写时使用了两个字符,但是在程序中它只是一个字符。可以自己来试验下:
>>> len(’\n’)
1
>>> len(’\’’)
1
如果我们就想在字符串中表示 \n
这两个字符,而不是让它表示换行,该怎么办?有两种方式:
使用 \\n
,将 \n
前面的反斜杠转义
>>> print(‘第一行\\n第二行’)
第一行\n第二行
使用原始字符串
原始字符串就是在字符串的起始引号前加上一个 r
或 R
字母,这样字符串中的内容将不会被转义,将按照原样输出。使用方法:
r'字符串内容'
>> print(r’第一行\n第二行’)
第一行\n第二行
我们之前所使用的字符串都被书写成一行,要想让字符串可以跨行书写,写成多行的形式,有两种方法:
字符串的每行末尾使用 \
续行
以多行的形式书写字符串,每行的末尾使用 \
续行。需要注意输出内容为一行。
string = '第一行\ 第二行\ 第三行'
>>> string = '第一行\
… 第二行\
… 第三行’
>>> print(string)
‘第一行第二行第三行’
可以看到这种方式可以让字符串以多行的方式来书写,但是输出内容还是被当作一行。如果想要输出内容为多行,需要在字符串中显式地使用 \n
进行换行。
>>> string = '第一行\n\
… 第二行\n\
… 第三行’
>>> print(string)
第一行
第二行
第三行
使用三个单引号或三个双引号来表示字符串
在 Python 中字符串也可以使用三个单引号或三个双引号来表示字符串,这样字符串中的内容就可以多行书写,并且被多行输出。
string = '''第一行 第二行 第三行'''
>>> string = ‘’‘第一行
… 第二行
… 第三行’’'
>>> print(string)
第一行
第二行
第三行
使用三引号的方式,字符串可被多行书写,且被多行输出,其中不需要显式地指明 \n
换行。
我们把列表、元组、字符串统称为序列。
使用 len()
函数获取序列长度
>>> letters = (‘a’, ‘b’)
>>> len(letters)
2
>>> letters = ‘abcd’
>>> len(letters)
4
获取序列中的一个子序列
获取序列中的子序列可以使用切片,以 [起始索引:结束索引]
表示。切片其实代表一个索引区间,这个区间是一个左闭右开区间,该区间内的所有元素作为子序列被返回。如:
>>> numbers = (1, 2, 3, 4, 5)
>>> numbers[0:2]
(1, 2)>>> numbers[2:4]
(3, 4)
>>> letters = ‘abcd’
>>> letters[1:5]
’bcd’
使用 +
符号来拼接两个序列
>>> letters_1 = (‘a’, ‘b’)
>>> letters_2 = (‘c’, ‘d’, ‘e’)
>>> letters_1 + letters_2
(‘a’, ‘b’, ‘c’, ‘d’, ‘e’)
>>> letters_1 = ‘ab’
>>> letters_2 = ‘cde’
>>> letters_1 + letters_2
’abcde’
使用 *
符号来重复序列中的元素
>>> letters = (‘a’, ‘b’)
>>> letters * 3
(‘a’, ‘b’, ‘a’, ‘b’, ‘a’, ‘b’)
>>> letters = ‘abcd’
>>> letters * 2
’abcdabcd’
注意上面的操作结果都是返回一个新的序列,不会对修改序列的内部元素。
列表、元组、字符串都是有序序列,都可以使用索引。
列表和元组中可以存放任意数据类型的元素,而字符串中只能存放字符。
列表是可变的,而元组和字符串是不可变的。
字典是一种用来存放若干键值对的数据类型。
什么是键值对呢?键值对就是两个对象,其中一个是用来做定位的数据,叫做键(Key),另一个是要存放的数据,叫做值(Value)。在字典中,键值对作为一个整体被存放,我们可以通过键来快速获取到对应的值。
在 Python 中字典用花括号({}
)来表示,键值对以 键:值
的方式写入花括号中,有多个键值对时用逗号分隔。
如 {'010': 'beijing', '021': 'shanghai'}
便是一个字典,其中包含两个键值对
'010': 'beijing'
'021': 'shanghai'
使用时,我们可以通过 '010'
快速查询到其对应的值是 'beijing'
。这就好比现实中的一本字典一样,通过拼音或偏旁来映射一个具体的字词,以此来实现字词的快速查找,而这个拼音或偏旁就相当于 Python 字典的键,而字词就相当于 Python 字典的值,它们在字典中是映射关系。
Python 字典中的键是有要求的,需要是不可变的类型,如元组、字符串、数字。而字典中的值可以是任意类型。字典本身是可变的,我们可以向其中添加、删除、修改键值对。
因为字典不是序列,更不是有序的,所有它没有列表那样的索引,也不能保证每个键值对的存放次序。
创建空的字典
字典 = {}
>>> empty_dict = {}
>>> empty_dict
{}
创建包含键值对的字典
字典 = {键1:值1, 键2:值2, ..., 键N:值N}
如城市和其对应的电话区号:
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes
{‘beijing’: ‘010’, ‘shanghai’: ‘021’}
向字典中增加键值对
字典[键] = 值
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes[‘tianjin’] = '022’
>>> codes
{‘beijing’: ‘010’, ‘shanghai’: ‘021’, ‘tianjin’: ‘022’}
使用这种方式时,若字典中没有这个键,则会创建这个键值对;若字典中原本已有这个键,则是修改键所对应的值。
通过键获取值
值 = 字典[键]
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes[‘beijing’]
‘010’
注意若键不存在则将抛出 KeyError
异常:
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes[‘a’]
Traceback (most recent call last):
File “”, line 1, in
KeyError: ‘a’
通过键获取值( get
方法)
如果通过键获取值时不希望 KeyError
异常抛出,可以使用 get
方法,若键不存在,则直接返回 None
。
值 = 字典.get(键)
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.get(‘a’)
>>>
返回的
None
代表什么都没有,所以没有任何值显示。
也可以给 get
方法传递第二个参数作为默认值,使得键不存在时直接返回默认值。
值 = 字典.get(键, 默认值)
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.get(‘a’, ‘000’)
>>> ‘000’
判断字典中是否包含某个键
布尔值 = 键 in 字典
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> ‘beijing’ in codes
True
>>> ‘guangzhou’ in codes
False
获取所有键
键的列表 = 字典.keys()
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.keys()
dict_keys([‘beijing’, ‘shanghai’])
获取到的所有键是以迭代器的形式存在,至于什么是迭代器我们将在之后的章节中介绍。在这里我们可以用 list()
函数将迭代器转换为列表。如下:
>>> list(codes.keys())
[‘beijing’, ‘shanghai’]
获取所有值
值的列表 = 字典.values()
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.values()
dict_values([‘010’, ‘021’])
获取到的所有值是以迭代器的形式存在,我们用 list()
函数将迭代器转换为列表。如下:
>>> list(codes.values())
[‘010’, ‘021’]
获取所有键值对的列表
值的列表 = 字典.items()
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.items()
dict_items([(‘beijing’, ‘010’), (‘shanghai’, ‘021’)])
获取到的所有键值对是以迭代器的形式存在,我们用 list()
函数将迭代器转换为列表。如下:
>>> list(codes.items())
[(‘beijing’, ‘010’), (‘shanghai’, ‘021’)]
列表中的每一个元素是都是二元组(即包含两个元素的元组),每个二元组的第一个元素是键,第二个元素是值。
通过键删除键值对
可以使用 pop
方法删除一个键值对,并将值返回。
值 = 字典.pop(键)
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.pop(‘beijing’)
’010’
>>> codes
{‘shanghai’: ‘021’}
如果 pop
一个不存在的键,则会抛出 KeyError
异常:
>>> codes.pop(‘a’)
Traceback (most recent call last):
File “”, line 1, in
KeyError: ‘a’
如果你不希望异常抛出,可以传递 pop
方法的第二个参数作为默认值。默认值仅在键不存在时生效,此时方法将直接返回这个默认值,且跳过删除操作:
值 = 字典.pop(键, 默认值)
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.pop(‘guangzhou’, ‘000’)
’000’
通过键删除键值对(del
方法)
也可以通过关键字 del
来删除键值对。
del 字典[键]
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> del codes[‘beijing’]
>>> codes
{‘shanghai’: ‘021’}
随机删除一个键值对
使用 popitem
随机删除一个键值对,并返回这个键值对的二元组,二元组的第一个元素是键,第二个元素是值。
键值二元组 = 字典.popitem()
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.popitem()
(‘shanghai’, ‘021’)
>>> codes
{‘beijing’: ‘010’}
清空所有键值对
键值二元组 = 字典.clear()
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.clear()
>>> codes
{}
修改键对应的值
字典[键] = 值
>>> codes = {‘beijing’: ‘010’}
>>> codes[‘beijing’] = '021’
>>> codes
{‘beijing’: ‘021’}
如果键不存在,则创建键值对。
用字典批量更新键值对
字典.update(另一字典)
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> codes.update({‘guangzhou’: ‘020’, ‘shanghai’: ‘000’})
>>> codes
{‘beijing’: ‘010’, ‘shanghai’: ‘000’, ‘guangzhou’: ‘020’}
可以看到字典中新增了 'guangzhou': '020'
这个键值对,同时将 'shanghai': '021'
修改为 'shanghai': '000'
。
字典的显著优势是可以通过键快速地查询数据。字典中的元素以键值对的形式存在,使用时通过键来获取和修改值,由于字典内部的特殊实现,字典通过键获取值的效率非常高。
如果我们希望将批量的数据存放起来,并且在需要时能以很高的执行效率来获取其中某个指定的数据,这时就可以使用字典。除此之外,如果我们想在程序中暂时维护一个映射关系,也可以使用字典,因为字典本质上就是一个映射关系。
如,我们可以将城市名和对应的区号保存在字典中,这样就可以通过城市名快速地查询到其区号,而不需要进行遍历。
area_codes = { '北京': '010', '上海': '021', '天津': '022', '重庆': '023', '沈阳': '024', '南京': '025', '武汉': '027', '成都': '028', }
>>> area_codes[‘成都’]
‘028’
>>> area_codes[‘南京’]
‘025’
集合是一个用于存放批量元素的数据类型,它不是有序的,其中的元素没有顺序关系。集合中的元素没有重复,重复的元素将被自动剔除最终只留下一个。
集合也是用花括号({}
)来表示,不同于字典的是,花括号中放的是一个个数据,而不是键值对。
集合是可变的,我们可以向其中添加、删除、修改元素。
创建包含元素的集合
集合 = {元素1, 元素2, 元素N}
>>> numbers = {1, 2, 3}
>>> numbers
{1, 2, 3}
创建空集合
集合 = set()
注意创建空集合不能直接使用 {}
,那样是表示空字典,而是使用 set()
,这才表示空集合。
>>> empty_set = set()
>>> empty_set
set()
向集合中添加一个元素
集合.add(元素)
>>> numbers = {1, 2}
>>> numbers.add(3)
>>> numbers
{1, 2, 3}
向集合中添加重复元素时,会被去重处理。
>>> numbers = {1, 2}
>>> numbers.add(2)
>>> numbers
{1, 2}
从另一集合中批量添加元素
集合.update(另一集合)
>>> numbers_1 = {1, 2}
>>> numbers_2 = {2, 3, 4}
>>> numbers_1.update(numbers_2)
>>> numbers_1
{1, 2, 3, 4}
可以看到,集合numbers_2
中的所有元素被添加到了集合 numbers_1
中,并且其中重复的元素被剔除仅保留一份。
集合不能像列表那样通过索引来获取元素,也不能像字典那样通过键来获取值,集合没法直接获取到某个指定的元素。想要获取元素,只能通过遍历的方式。
虽然集合不能直接获取到元素,但是我们依然可以用 in
关键字来判断元素是否存在于集合中。
查看元素是否存在于集合中
布尔值 = 元素 in 集合
>>> letters = {‘a’, ‘b’, ‘c’}
>>> ‘a’ in letters
True
>>> ‘z’ in letters
False
随机删除一个元素,并返回这个元素
元素 = 集合.pop()
使用 pop
方法随机删除一个元素的时候,这个元素会被返回。
>>> numbers = {1, 2, 3}
>>> numbers.pop()
1
>>> numbers.pop()
2
>>> numbers
{3}
删除一个指定的元素
集合.remove(元素)
>>> numbers = {1, 2, 3}
>>> numbers.remove(1)
>>> numbers
{2, 3}
如果要删除的元素不存在,则抛出 KeyError
异常:
>>> numbers = {1, 2, 3}
>>> numbers.remove(4)
Traceback (most recent call last):
File “”, line 1, in
KeyError: 4
删除一个指定的元素,且不抛出 KeyError
异常
使用 remove
方法删除一个不存在的元素时,会抛出 KeyError
异常,如果我们不想让异常抛出,可以使用 discard
方法。
集合.discard(元素)
>>> numbers = {1, 2, 3}
>>> numbers.discard(4)
>>> numbers
{1, 2, 3}
清空所有元素
集合.clear()
与列表和字典一样,想要清空所有元素,可以使用 clear
方法。
>>> numbers = {1, 2, 3}
>>> numbers.clear()
>>> numbers
set()
顺便考大家一个问题,为什么元组没有这个方法?因为元组是不可变的!我们不能删除元组的元素,也不能添加和修改元素。
看到这里你可能会想,集合不就是阉割版的列表嘛?不是的,集合的功能不止于此。
Python 中的集合和数学中的集合颇为相似,首先集合的所有元素都是唯一的,不存在重复;此外集合有子集、超集的概念,也可以进行交集、并集、差集的运算。
求交集
可以通过 intersection
方法求多个集合的交集。
交集 = 集合1.intersection(集合2, 集合3, 集合N)
>>> numbers_1 = {1, 2, 3}
>>> numbers_2 = {2, 3, 4}
>>> numbers_3 = {3, 4, 5}
>>> numbers_1.intersection(numbers_2, numbers_3)
{3}
也可以直接使用与运算符 &
来代替,完全等效:
交集 = 集合1 & 集合2 & 集合N
>>> numbers_1 & numbers_2 & numbers_3
{3}
求并集
并集 = 集合1.union(集合2, 集合3, 集合N)
>>> numbers_1 = {1, 2, 3}
>>> numbers_2 = {2, 3, 4}
>>> numbers_3 = {3, 4, 5}
>>> numbers_1.union(numbers_2, numbers_3)
{1, 2, 3, 4, 5}
也可以直接使用或运算符 |
来代替,完全等效:
并集 = 集合1 | 集合2 | 集合N
>>> numbers_1 | numbers_2 | numbers_3
{1, 2, 3, 4, 5}
求差集
差集 = 集合1.difference(集合2, 集合3, 集合N)
>>> numbers_1 = {1, 2, 3}
>>> numbers_2 = {2, 3, 4}
>>> numbers_3 = {3, 4, 5}
>>> numbers_1.difference(numbers_2, numbers_3)
{1}
也可以直接使用运算符 -
来代替,完全等效:
差集 = 集合1 - 集合2 - 集合N
>>> numbers_1 - numbers_2 - numbers_3
{1}
判断是否为子集
布尔值 = 集合1.issubset(集合2)
判断 集合1
是否为 集合2
的子集。
>>> numbers_1 = {2, 3}
>>> numbers_2 = {1, 2, 3}
>>> numbers_1.issubset(numbers_2)
True
>>> numbers_3 = {3, 4}
>>> numbers_1.issubset(numbers_3)
False
判断是否为超集
布尔值 = 集合1.issuperset(集合2)
判断 集合1
是否为 集合2
的子集。
>>> numbers_1 = {1, 2, 3}
>>> numbers_2 = {2, 3}
>>> numbers_1.issuperset(numbers_2)
True
>>> numbers_3 = {3, 4}
>>> numbers_1.issuperset(numbers_3)
False
集合运算在编程时有什么用呢?以差集为例举个例子。
假如大学里有一个班,班里同学的花名册是「赵大,钱二,孙三,李四,周五,吴六,郑七,王八」。有一天上课,老师要求同学们在一张白纸上签到,大家陆续写上了自己的名字,上面有「周五,李四,王八,赵大,钱二,冯九,陈十」。哪些人缺席了呢?
要判断哪些人缺席了,通常的做法时,逐一从签到表上取出名字,然后去花名册上寻找并做标记,最终花名册上没被标记的名字便是缺席的。有些麻烦,这可苦了助教了。
我们可以用 Python 集合来快速解决这个问题。将花名册上的名字保存在集合中,将签到表上的名字保存在另一个集合中,然后求一下差集。如下:
>>> 花名册 = {‘赵大’, ‘钱二’, ‘孙三’, ‘李四’, ‘周五’, ‘吴六’, ‘郑七’, ‘王八’}
>>> 签到表 = {‘周五’, ‘李四’, ‘王八’, ‘赵大’, ‘钱二’, ‘冯九’, ‘陈十’}
>>> 花名册 - 签到表
{‘吴六’, ‘孙三’, ‘郑七’}
吴六,孙三,郑七没来!
我们用反过来用 签到表 - 花名册
看看:
>>> 签到表 - 花名册
{‘陈十’, ‘冯九’}
还有两个旁听生!
集合非常重要的一个特性是元素无重复,每个元素都是唯一的,重复的元素将被自动剔除(去重)。
所以如果我们需要存放一系列的数据,并且不希望其中出现重复,那么就可以使用集合。
另外如果想计算两个数据集的交集、并集、差集,使用集合来承载数据再合适不过了,集合自带的集合运算能轻松解决这些问题。
我们可以通过 len()
函数来获取字典中的键值对数量和集合中的元素数量。
>>> codes = {‘beijing’: ‘010’, ‘shanghai’: ‘021’}
>>> len(codes)
2
>>> numbers = {1, 2, 3, 4}
>>> len(numbers)
4
字典是一种用来存放若干键值对的数据类型,可通过键来快速查找值。
字典的键需要是不可变的类型,如数字,字符串和元组。字典的值可以是任意类型。字典本身是可变的,所以可向其中添加、修改、删除键值对。
集合是一个用于存放批量元素的序列。它不是有序的,且元素不会有重复。集合也是可变的,我们可以向其中添加、删除、修改元素。