在之前的知识中,我们储存一个数据都需要将它赋给一个具体的变量,这样的方法笨重不美观。比如我们做一下下面这个练习。将两颗骰子同时掷6000次,统计每次掷出后两颗骰子相加的点数。这个任务对大家来说应该是非常简单的,我们可以用2到12均匀分布的随机数来模拟掷色子,然后用11个变量分别记录每个点数出现的次数,相信大家都能写出下面的代码。
import random
a_2 = 0
a_3 = 0
a_4 = 0
a_5 = 0
a_6 = 0
a_7 = 0
a_8 = 0
a_9 = 0
a_10 = 0
a_11 = 0
a_12 = 0
for _ in range(1, 60001):
num_1 = random.randrange(1, 7)
num_2 = random.randrange(1, 7)
total = num_2 + num_1
if total == 2:
a_2 += 1
elif total == 3:
a_3 += 1
elif total == 4:
a_4 += 1
elif total == 5:
a_5 += 1
elif total == 6:
a_6 += 1
elif total == 7:
a_7 += 1
elif total == 8:
a_8 += 1
elif total == 9:
a_9 += 1
elif total == 10:
a_10 += 1
elif total == 11:
a_11 += 1
elif total == 12:
a_12 += 1
print(f'掷出2点:{a_2}次')
print(f'掷出3点:{a_3}次')
print(f'掷出4点:{a_4}次')
print(f'掷出5点:{a_5}次')
print(f'掷出6点:{a_6}次')
print(f'掷出7点:{a_7}次')
print(f'掷出8点:{a_8}次')
print(f'掷出9点:{a_9}次')
print(f'掷出10点:{a_10}次')
print(f'掷出11点:{a_11}次')
print(f'掷出12点:{a_12}次')
大家可以看到用定义变量的方法来储存数据已经不能够满足如今大数据环境下我们的需求了。所以我们需要寻找新的储存数据的方法。
在Python中我们可以通过容器类型的变量来保存和操作多个数据,常见的有列表(list)
、元组(tuple)
、集合(set)
、字典(dict)
,我们首先为大家介绍列表(list)
这种新的数据类型。
一、列表的定义和使用
1. 列表的定义
在Python中,列表是由一系元素按特定顺序构成的数据序列,这样就意味着定义一个列表类型的变量,可以保存多个数据,而且允许有重复的数据。列表中的每个元素都分配一个数字 - 它的位置(或索引),第一个索引是0,第二个索引是1,依此类推。
nums = [25, 36, 29, 75, 60] # 索引分别为0,1,2,3,4
rules = ['热爱祖国', '热爱人民', '热爱中国共产党'] # 索引分别为0,1,2
2. 列表的创建方法
(1)字面量语法
在Python中,可以使用[]
字面量语法来定义列表,列表中的多个元素用逗号进行分隔,代码如下所示。
list1 = ['apple', 'orange', 'pitaya']
items = [1, 2, 3, 4, 5, 6]
(2)构造器语法
Python内置的list
函数将其他序列变成列表。准确的说,list
并不是一个函数,而是创建列表对象的构造器。示例如下:
list2 = list(range(1, 10, 2)) # list2 = [1, 3, 5, 7, 9]
(3)生成式(推导式)语法
在Python中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。列表生成式即List Comprehensions
,是Python内置的非常简单却强大的可以用来创建list的生成式。示例如下:
list3 = [i ** 2 for i in range(1, 10)] # [1, 4, 9, 16, 25, 36, 49, 64, 81]
list4 = [i for i in range(1, 20) if i % 2 == 0] # [2, 4, 6, 8, 10, 12, 14, 16, 18]
3. 列表的运算符
列表支持拼接、重复、成员运算、索引和切片以及比较运算,对此不再进行赘述,请大家参考下面的代码。
items1 = [65, 12, 100, 68, 67, 0]
items2 = [15, 58, 96]
# 列表的拼接
items3 = items1 + items2
print(items3) # [65, 12, 100, 68, 67, 0, 15, 58, 96]
# 列表的重复
items4 = ['hello'] * 3
print(items4) # ['hello', 'hello', 'hello']
# 列表的成员运算
print(50 in items3) # False
print('hello' in items4) # True
# 获取列表的长度(元素个数)
size = len(items3)
print(size) # 9
# 列表的索引
print(items3[0], items3[-size]) # 65 65
items3[-1] = 22
print(items3[size - 1], items3[-1]) # 22 22
# 列表的切片
print(items3[:5]) # [65, 12, 100, 68, 67]
print(items3[4:]) # [67, 0, 15, 58, 22]
print(items3[-5:-7:-1]) # [67, 68]
print(items3[::-2]) # [22, 15, 67, 100, 65]
# 列表的比较运算
items5 = [1, 2, 3, 4]
items6 = list(range(1, 5))
# 两个列表比较相等性比的是对应索引位置上的元素是否相等
print(items5 == items6) # True
items7 = [3, 2, 1]
# 两个列表比较大小比的是对应索引位置上的元素的大小
print(items5 <= items7) # True
值得一提的是,由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素,对列表做索引操作一样要注意索引越界的问题。
4. 列表的遍历
如果想逐个取出列表中的元素,可以使用for
循环的。如果想要同时取出元素和它的索引,先通过enumerate函数
对列表进行预处理,循环遍历的时候既可以获取到索引(下标)又可以获取到元素。下面是三种方法的展示:
(1)第一种遍历列表中的数据
items4 = [77, 42, 100, 68, 5]
for i in range(len(items4)):
print(items4[i], end=' ') # 77 42 100 68 5
(2)第二种遍历列表中的数据
items4 = [77, 42, 100, 68, 5]
for i in items4:
print(i, end=' ') # 77 42 100 68 5
(3)第三种遍历列表中的数据
items4 = [77, 42, 100, 68, 5]
for i, x in enumerate(items4):
print(i, x)
# 0 77
# 1 42
# 2 100
# 3 68
# 4 5
二、列表的方法
1.元素的下标和次数
列表类型的index
方法可以查找某个元素在列表中的索引位置;因为列表中允许有重复的元素,所以列表类型提供了count
方法来统计一个元素在列表中出现的次数。请看下面的代码。
# index() ---> 查找元素在列表中的索引(下标)
items = ['banana', 'grape', 'apple', 'waxberry', 'pitaya', 'apple']
print(items.index('watermelon')) # ValueError: 'watermelon' is not in list
if 'strawberry' in items:
print(items.index('strawberry')) # strawberry不在列表,所以不输出
if 'apple' in items:
print(items.index('apple')) # 2
if 'apple' in items[3:]:
print(items.index('apple', 3)) # 5 (从索引为3 的waxberry开始查找)
再看看下面这段代码
# count() ---> 统计元素在列表中出现的次数
items = ['apple', 'grape', 'apple', 'waxberry', 'pitaya', 'apple']
print(items.count('apple')) # 3
print(items.count('strawberry')) # 0
2.增添、删除和清空元素
(1)增添元素
items = ['banana', 'grape', 'apple']
# append() ---> 在列表末尾增添元素
items.append('blueberry')
# insert() ---> 在列表指定索引位置增添元素
items.insert(1, 'watermelon')
print(items) # ['banana', 'watermelon', 'grape', 'apple', 'blueberry']
(2)删除元素
items = ['banana', 'watermelon', 'grape', 'apple', 'blueberry', 'pitaya']
# pop() ---> 默认删除列表末尾元素,也可删除指定索引位置元素
items.pop()
print(items) # ['banana', 'watermelon', 'grape', 'apple', 'blueberry']
items.pop(2)
print(items) # ['banana', 'watermelon', 'apple', 'blueberry']
# del ---> 删除指定索引位置元素,但是没有返回值;pop()可以返回删除值
del items[0]
print(items) # ['watermelon', 'apple', 'blueberry']
print(items.pop()) # blueberry
# remove() ---> 删除列表中指定元素
while 'apple' in items:
items.remove('apple')
print(items) # ['watermelon]
(3)清空元素
# clear() --->清空列表元素
items = ['banana', 'watermelon', 'grape', 'apple']
items.clear()
print(items) # []
注意:
在使用remove
方法删除元素时,如果要删除的元素并不在列表中,会引发ValueError
异常,错误消息是:list.remove(x): x not in list
。在使用pop
方法删除元素时,如果索引的值超出了范围,会引发IndexError
异常,错误消息是:pop index out of range
。
3. 元素排序和反转
(1)元素排序
items = [54, 72, 19, 34, 24, 66]
# sort() --->排序(默认从小到大排序)
items.sort()
print(items) # [19, 24, 34, 54, 66, 72]
# 可以修改reverse参数控制升序或降序(True为从大到小,False反之)
items = [54, 72, 19, 34, 24, 66]
items.sort(reverse=True)
print(items) # [72, 66, 54, 34, 24, 19]
(2)元素反转
items = [1, 2, 3, 4, 5, 6]
# 使用切片让元素反转
print(items[::-1]) # [6, 5, 4, 3, 2, 1]
# reverse() --->元素反转
items.reverse()
print(items) # [6, 5, 4, 3, 2, 1]
三、嵌套的列表
Python语言没有限定列表中的元素必须是相同的数据类型,也就是说一个列表中的元素可以任意的数据类型,当然也包括列表。如果列表中的元素又是列表,那么我们可以称之为嵌套的列表。嵌套的列表可以用来表示表格或数学上的矩阵,例如:我们想保存5个学生3门课程的成绩,可以定义一个保存5个元素的列表保存5个学生的信息,而每个列表元素又是3个元素构成的列表,分别代表3门课程的成绩。但是,一定要注意下面的代码是有问题的。
scores = [[0] * 3] * 5
print(scores) # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
看上去我们好像创建了一个5 * 3
的嵌套列表,但实际上当我们录入第一个学生的第一门成绩后,你就会发现问题来了,我们看看下面代码的输出。
# 嵌套的列表需要多次索引操作才能获取元素
scores[0][0] = 95
print(scores)
# [[95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0]]
我们不去过多的解释为什么会出现这样的问题,如果想深入研究这个问题,可以通过Python Tutor网站的可视化代码执行功能,看看创建列表时计算机内存中发生了怎样的变化,下面的图就是在这个网站上生成的。建议大家不去纠结这个问题,现阶段只需要记住不能用[[0] * 3] * 5]
这种方式来创建嵌套列表就行了。那么创建嵌套列表的正确做法是什么呢?我们使用列表的生成式来创建,下面的代码会给你答案。
scores = [[0] * 3 for _ in range(5)]
scores[0][0] = 95
print(scores)
# [[95, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
以上就是常用数据结构之列表的基本知识。Get It!