本来以为Python的基础内容已经告一段落,但在网上一番查找后找到了一些有趣的内容。
既然主要是关于列表的,那就单独再写一篇吧。
这里提供两个不错的网络资源:
-
,和出版社出版的译者不同,译者完全是在为爱发电,并且免费公开。
-
,Python官方文档,让我很诧异的是居然有中文版,翻译的还不错。
解压
通常我们只会在解压一些压缩文件的时候这么称呼这种操作,但有趣的是Python的基础容器也支持一种叫解压的操作,而且还真的挺形象。
people = ["jack chen", "brus lee"]
jackChen = people[0]
brusLee = people[1]
我们看这样一个例子,有一个people
队列,需要从中抽取特定部位的元素然后分别赋值到指定变量。
以上是我们常见的额写法,但其实有更简洁的Python特有的写法:
people = ["jack chen", "brus lee"]
jackChen, brusLee = people
print(jackChen, brusLee)
两者完全等效,甚至如果people仅仅是中间变量的话,连people都可以省略:
jackChen, brusLee = ["jack chen", "brus lee"]
print(jackChen, brusLee)
这就是解压操作。
嗯,这很Python。
具体来说,Python的解压操作就是把一个容器中的元素分别赋予一组单独的变量,但需要注意的是两者数目必须相等,如果不等就会出现错误。
看起来虽然强大但颇有局限性,但Python的解压操作不仅仅局限于此。
我们假设有这么一个队列:
numbers = [i for i in range(1, 20, 2)]
print(numbers)
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
现在需要抽取前三个和最后一个元素,如果用Python的方式要如何做?
numbers = [i for i in range(1, 20, 2)]
print(numbers)
num1, num2, num3, *numOthers, numEnd = numbers
print(num1, num2, num3, numEnd)
print(numOthers)
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# 1 3 5 19
# [7, 9, 11, 13, 15, 17]
是不是很有趣?
*numOthers
的使用很像我们在中提到的可变参数的使用。事实两者也都类似,都是表明这里将是一个列表,用于接受数目不确定的元素。
类似的,*
不仅可以用于中间,也可以用于解压序列的头部或尾部:
numbers = [i for i in range(1, 20, 2)]
print(numbers)
*_, last1, last2 = numbers
print(last1, last2)
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# 17 19
就像上面展示的,如果我们在解压时候不需要用到某个位置的变量,仅仅需要起到一个占位符的作用,那我们可以使用任意临时变量名之类的方式名命变量,通常是使用_
。
特别的,解压在处理一些长度不确定的容器时格外有用:
people = [["jack chen", 16, "actor"], ["brus Lee", "engineer"]]
for person in people:
name, *info = person
print("name is ", name, "person info is ", info)
# name is jack chen person info is [16, 'actor']
# name is brus Lee person info is ['engineer']
我们可以使用解压快速讲一些特定元素和其它不确定元素分离,以方便进一步处理。
拼接和重复
Python有很多有趣的操作,比如+
一般而言是针对字符串进行拼接,这很好理解,在其它语言中也有类似的用法。
但在Python中,可以使用+
对容器进行拼接:
numbers1 = [1, 2, 3]
numbers2 = [7, 8, 9]
numbers3 = numbers1+numbers2
print(numbers3)
# [1, 2, 3, 7, 8, 9]
类似的还有*
,在Python中除了数学计算,我们还经常用于字符串输出:
print('-'*10)
# ----------
相比其它语言这的确很方便,但不仅于此,*
还可以用于容器:
numbers = [1, 2, 3]
print(numbers*3)
# [1, 2, 3, 1, 2, 3, 1, 2, 3]
但我们需要注意的是,通过这种复制拼接得到的列表,其中复制出来的部分并不是“新建”的,是对原有元素的引用。
比如我们看下面这个例子:
numbers = [[]]*3
print(numbers)
numbers[0].append(1)
print(numbers)
# [[], [], []]
# [[1], [1], [1]]
是不是很奇怪?我们明明只改变了其中一个元素,但所有的三个元素都改变了,这正是因为其它两个元素是被复制出来的,他们三个都指向同一个列表。
如果我们需要创建一个“确确实实”的二维列表,我们可以这样做:
numbers = [[] for i in range(0, 3)]
print(numbers)
numbers[0].append(1)
numbers[1].append(2)
numbers[2].append(3)
print(numbers)
# [[], [], []]
# [[1], [2], [3]]
好了,这算是某种意义上关于列表的one more thing吧。
需要说明的是以上是用列表举例,但字典集合等其它容器也是可以使用这些操作的,这里不再重复说明。
谢谢阅读。
本系列文章的代码都存放在Github项目:
文章评论