大家好~~~~
作者前几天到NIIT实训去了,学了“如何在博客了加入背景音乐”(雾)。
老师说,用这个:
<audio src="blablablabla……" controls="controls" loop="loop">
您的浏览器实在是太先进了
</audio>
标签就可以了!
话说……播放列表怎么做QAQ
扯远了,我们来接着学习Python吧。
这节课我们来讲Python中的四种特殊的数据类型,它们的特点是:
- 由0个、1个或多个基本类型的数据组成
- 可以层层嵌套
它们就是:
(标题上那四个……)
我们先来学习这里面的“列表”和“元组”。
Python中的“列表”、“元组”和“字符串”都是序列对象。
什么叫做“序列对象”呢?
序列对象就是具有下列特点的对象:
- 成员有序排列
- 可以通过下标访问
- 可以迭代
元组(Tuple)
元组是一种不可变的序列对象。
一个元组的表示方式是:
(对象1, 对象2, 对象3)
其中的“对象”可以是任何一种数据类型,包括本节所讲的所有类型。
>>> (123, '你好', ['hello'])
(123, '你好', ['hello'])
这就是一个元组,其中第一个对象是一个int,第二个对象是一个string,第三个对象是一个列表(List)
一个元组被创建之后就不能被修改,所有的“修改”操作只是完全重新创建了一个新的元组,然后取代了原有的元组。
有时候元组可以没有括号,但括号+逗号+2个或2个以上的对象所构成的,一定是一个独立的“元组”。
例如:
>>> 1,2
(1, 2)
>>> ((1,2))
(1, 2)
>>> 1,(2)
(1, 2)
>>> (1,(2))
(1, 2)
>>> 1,(2,3)
(1, (2, 3))
第一到第四种情况,它们都是等价的。都是同一个元组对象:(1, 2)
第五中情况为元组嵌套元组。
元组在“给函数传递多个参数”、“一个函数同时返回多个值”等场合中都有应用。
这里举一个简单的例子:
>>> a = 1
>>> b = 2
>>> a,b = b,a
>>> a
2
>>> b
1
这就是两数交换的写法,a, b = b, a。
相当于:
(a, b) = (b, a)
temp_b = b
temp_a = a
a = temp_b
b = temp_a
你问我[a, b] = [b, a]可不可以?
当然可以。
a和b都是不可变对象,它们的值是不会被修改的。
当然,也没有创建出两个新的int。
这个“两数交换”其实是交换了a和b的引用,现在通过a访问到的是之前的b,通过b访问到的是之前的a。它们在内存中的实际位置没有发生变化。值也没有发生变化。
你可以通过下标访问元组的任意项,语法是:有序对象[位置]。Python中的[]非常强大,我们一会再学。
>>> (1,2)[1]
2
列表(List)
列表和元组很相似,但有一点区别:列表的内容可以被修改。
创建了一个列表之后,你可以对它进行增删改查操作。
一个列表的表示方式是:
[对象1, 对象2, 对象3]
这是一个列表的例子:
>>> a = [1, '2', [3]]
>>> a
[1, '2', [3]]
其中的对象从左往右依次为int,string,list。
我们可以当数组用:
>>> a[0]
1
可以当堆栈用:
>>> a.append(4)
>>> a
[1, '2', [3], 4]
>>> a.pop()
4
>>> a
[1, '2', [3]]
可以拼接两个List:
>>> a.extend([4, 5, 6])
>>> a
[1, '2', [3], 4, 5, 6]
当然,你可以将两个List相加,它会返回一个由两个List拼接而成的新List。由于是完全重新创建的List,所以耗时长,消耗内存大。一般不建议使用。
可以当队列用:
>>> a.append('abc')
>>> a
[1, '2', [3], 4, 5, 6, 'abc']
>>> a.pop(0)
1
>>> a
['2', [3], 4, 5, 6, 'abc']
pop(下标)将返回并删除指定位置的元素。如果不指定参数,则目标为队列末尾。
可以插队:
>>> a.insert(3, 'd')
>>> a
['2', [3], 4, 'd', 5, 6, 'abc']
使用insert(位置, 内容)可以在指定位置(从0到n-1)插入一个对象。
可以排序:
>>> a = [6, 4, 2, 1, 3, 5]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5, 6]
如果List中有多种数据类型,依然可以对它进行排序,Python会尽可能让其按照一定的顺序排列
sort()函数会直接修改List的内容,不会返回数据。
如果你想保留原List,请使用sorted()函数。
>>> a = [6, 4, 2, 1, 3, 5]
>>> b = sorted(a)
>>> a
[6, 4, 2, 1, 3, 5]
>>> b
[1, 2, 3, 4, 5, 6]
使用reverse()方法可以翻转一个List的顺序:
>>> b.reverse()
>>> b
[6, 5, 4, 3, 2, 1]
可以删除List中一个指定内容的项:
>>> a = ['abc', 1, 2, 'abc', 4, 5]
>>> a.remove(4)
>>> a
['abc', 1, 2, 'abc', 5]
>>> a.remove('abc')
>>> a
[1, 2, 'abc', 5]
>>> a.remove('abc')
>>> a
[1, 2, 5]
是否还记得,Python中所有的变量名都是引用?(在上一节中提到过)
我们可以试验一下。
现在有一个列表a:
a = [1, 2, 3]
你想复制一份a,如何操作?
>>> b = a
>>> b
[1, 2, 3]
看起来好像复制了一份a。
>>> a.append(4)
>>> b
[1, 2, 3, 4]
没错,a和b只是同一个List的两个引用。或者你可以理解为“两个名称”。其实内存中只有一个List……
那……怎么复制呢?
当然,你可以遍历这个List,创建一个新的List,把每个项目一个一个加进去。
不过,Python那强大的[]运算符能更加省事。
它不仅可以访问序列中的一个对象,还可以访问序列中的一组对象。
如果想复制一个List,你可以这么做:
>>> b = a[:]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4]
这才是两个List。
Python 切片
话说a[:]是什么鬼……
好的,现在讲一讲a[:]是什么鬼。
Python的[]有下列三种用法:
有序对象[位置]
返回一个序列指定位置的对象,这个位置取值范围为从0 ~ n-1(顺序访问),也可以从-1 ~ -n(逆序访问)有序对象[起始位置:终止位置]
返回一个序列中指定始末位置的片段(不包含终止位置对应的对象),若起始位置大于等于终止位置,则返回空序列。位置同样支持负数值。(注意……返回的序列顺序不会发生变化)- 有序对象[起始位置:终止位置:步进值]
在上面的基础上,加上一个“对象之间的距离”值。
这称为“切片”。
来试一试吧:
>>> a = list(range(1,21))
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
在Python 3中,range()返回一个迭代器,支持1~3个参数,1个参数返回从0 ~ n-1的迭代器,其余情况和上面的“切片”类似……区别就是步进值允许负数,返回一个倒序的数列迭代器。
使用list()函数将迭代器转换为List对象。
>>> a[-1]
20
>>> a[-2]
19
>>> a[5]
6
>>> a[1:5]
[2, 3, 4, 5]
>>> a[:5]
[1, 2, 3, 4, 5]
>>> a[14]
15
>>> a[14:-1]
[15, 16, 17, 18, 19]
>>> a[14:]
[15, 16, 17, 18, 19, 20]
>>> a[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
是不是突然理解了a[:]……
>>> a[::2]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
没错,只要冒号数量对得上,位置可以为空,表示开始位置/末尾位置。步进值也可以为空,默认为1。
由此可推测:
a[::]的效果和a[:]是一样的。
>>> a[::]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
所有的序列对象都可以这么玩:
>>> s = '我从未见过如此厚颜无耻之人'
>>> s[3:]
'见过如此厚颜无耻之人'
>>> s[::2]
'我未过此颜耻人'
字典(Dict)
字典是用key-value方式存储的数据结构。
使用这种数据结构,你可以通过key,在很短的时间内查找到value。
这适合存储类似于名字-成绩,单词-含义,属性-值……这样的成对出现的数据。
话不多说,直接看示范:
>>> a = {'小明': 100, '小红': 97, '小刚': 86}
>>> a['小明']
100
>>> a['小埋'] = 99
>>> a
{'小埋': 99, '小红': 97, '小明': 100, '小刚': 86}
它的格式是:
{key1: value1, key2: value2, key3: value3}
访问方式是:
字典名[key]
key必须是不可变类型。
key必须是不可变类型。
key必须是不可变类型。
使用可变对象作为key会报错:
>>> a[[1, 2, 3]] = 12
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
(从错误信息来看,Dict的索引是基于Hash的)
访问不存在的key会报错:
>>> a['BL']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'BL'
怎么避免这个错误呢?使用dict提供的get方法即可。
>>> a.get('BL')
>>> a.get('BL', 1)
1
>>> a.get('小埋')
99
字典.get(key):如果key不存在,返回None。
字典.get(key, 返回值):如果key不存在,返回用户指定的值。
你可以检查key是否存在:
>>> '小埋' in a
True
>>> 'BL' in a
False
可以移除字典中的项目:
>>> a.pop('小埋')
99
>>> a
{'小红': 97, '小明': 100, '小刚': 86}
>>> del a['小明']
>>> a
{'小红': 97, '小刚': 86}
注意:Dict内部的数据存放顺序和添加的顺序无关。
Dict的两个特点:
- 查找速度快
- 浪费内存多
集合(set)
和字典类似,但只有key,没有value。
和数学定义的“集合”类似,集合中的元素具有确定性、互异性和无序性。(23333333)
集合的使用方式:
>>> a = {1, 2, 3}
>>> a
{1, 2, 3}
>>> a.add(4)
>>> a
{1, 2, 3, 4}
>>> a.remove(1)
>>> a
{2, 3, 4}
>>> a.add(4)
>>> a.add(4)
>>> a.add(4)
>>> a.add(4)
>>> a
{2, 3, 4}
和数学上的集合一样,可以求交集和并集:
>>> b = {1, 2, 3}
>>> b & a
{2, 3}
>>> b | a
{1, 2, 3, 4}
和dict一样,不可在set中放入“不可变对象”。
>>> a.add([1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'