常用数据结构之列表-1

将一颗色子掷6000次,统计每种点数出现的次数

import random

f1 = 0
f2 = 0
f3 = 0
f4 = 0
f5 = 0
f6 = 0
for _ in range(6000):
    face = random.randrange(1, 7)
    if face == 1:
        f1 += 1
    elif face == 2:
        f2 += 1
    elif face == 3:
        f3 += 1
    elif face == 4:
        f4 += 1
    elif face == 5:
        f5 += 1
    else:
        f6 += 1
print(f'1点出现了{f1}次')
print(f'2点出现了{f2}次')
print(f'3点出现了{f3}次')
print(f'4点出现了{f4}次')
print(f'5点出现了{f5}次')
print(f'6点出现了{f6}次')

创建列表

在 Python 中,列表是由一系列元素按特定顺序构成的数据序列,这就意味着如果我们定义一个列表类型的变量,可以用它来保存多个数据。使用[]字面量语法来定义列表

items1 = [35, 12, 99, 68, 55, 35, 87]
items2 = ['Python', 'Java', 'Go', 'Kotlin']
items3 = [100, 12.3, 'Python', True]
print(items1)  # [35, 12, 99, 68, 55, 35, 87]
print(items2)  # ['Python', 'Java', 'Go', 'Kotlin']
print(items3)  # [100, 12.3, 'Python', True]

不建议将不同类型的元素放在同一个列表

使用type函数来查看变量的类型,

还可以通过 Python 内置的list函数将其他序列变成列表,它是创建列表对象的构造器。

items4 = list(range(1, 10))
items5 = list('hello')
print(items4)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(items5)  # ['h', 'e', 'l', 'l', 'o']

列表的运算

+运算符实现两个列表的拼接

items5 = [35, 12, 99, 45, 66]
items6 = [45, 58, 29]
items7 = ['Python', 'Java', 'JavaScript']
print(items5 + items6)  # [35, 12, 99, 45, 66, 45, 58, 29]
print(items6 + items7)  # [45, 58, 29, 'Python', 'Java', 'JavaScript']
items5 += items6
print(items5)  # [35, 12, 99, 45, 66, 45, 58, 29]

使用*运算符实现列表的重复运算,*运算符会将列表元素重复指定的次数,

print(items6 * 3)  # [45, 58, 29, 45, 58, 29, 45, 58, 29]
print(items7 * 2)  # ['Python', 'Java', 'JavaScript', 'Python', 'Java', 'JavaScript']

使用innot in运算符判断一个元素在不在列表中

print(29 in items6)  # True
print(99 in items6)  # False
print('C++' not in items7)     # True
print('Python' not in items7)  # False

[]运算符,通过在[]中指定元素的位置来访问该元素,这种运算称为索引运算。

[]的元素位置可以是0N - 1的整数,也可以是-1-N的整数,分别称为正向索引和反向索引,其中N代表列表元素的个数。对于正向索引,[0]可以访问列表中的第一个元素,[N - 1]可以访问最后一个元素;对于反向索引,[-1]可以访问列表中的最后一个元素,[-N]可以访问第一个元素。

items8 = ['apple', 'waxberry', 'pitaya', 'peach', 'watermelon']
print(items8[0])   # apple
print(items8[2])   # pitaya
print(items8[4])   # watermelon
items8[2] = 'durian'
print(items8)      # ['apple', 'waxberry', 'durian', 'peach', 'watermelon']
print(items8[-5])  # 'apple'
print(items8[-4])  # 'waxberry'
print(items8[-1])  # watermelon
items8[-4] = 'strawberry'
print(items8)      # ['apple', 'waxberry', 'durian', 'peach', 'watermelon']

使用索引运算的时候要避免出现索引越界的情况,对于上面的items8,如果我们访问items8[5]items8[-6],就会引发IndexError错误,对于只有五个元素的列表items8,有效的正向索引是04,有效的反向索引是-1-5

如果希望一次性访问列表中的多个元素,可以使用切片运算。切片运算是形如[start:end:stride]的运算符

start代表访问列表元素的起始位置,end代表访问列表元素的终止位置(终止位置的元素无法访问),而stride则代表了跨度,简单的说就是位置的增量,访问的第一个元素在start位置,那么第二个元素就在start + stride位置,当然start + stride要小于end

print(items8[1:3:1])     # ['waxberry', 'pitaya']
print(items8[0:3:1])     # ['apple', 'waxberry', 'pitaya']
print(items8[0:5:2])     # ['apple', 'pitaya', 'watermelon']
print(items8[-4:-2:1])   # ['waxberry', 'pitaya']
print(items8[-2:-6:-1])  # ['peach', 'pitaya', 'waxberry', 'apple']

如果start值等于0,那么在使用切片运算符时可以将其省略;如果end值等于NN代表列表元素的个数,那么在使用切片运算符时可以将其省略;如果stride值等于1,那么在使用切片运算符时也可以将其省略。

print(items8[1:3])     # ['waxberry', 'pitaya']
print(items8[:3:1])    # ['apple', 'waxberry', 'pitaya']
print(items8[::2])     # ['apple', 'pitaya', 'watermelon']
print(items8[-4:-2])   # ['waxberry', 'pitaya']
print(items8[-2::-1])  # ['peach', 'pitaya', 'waxberry', 'apple']

通过切片操作修改列表中的元素

items8[1:3] = ['x', 'o']
print(items8)  # ['apple', 'x', 'o', 'peach', 'watermelon']
nums1 = [1, 2, 3, 4]
nums2 = list(range(1, 5))
nums3 = [3, 2, 1]
print(nums1 == nums2)  # True
print(nums1 != nums2)  # False
print(nums1 <= nums3)  # True
print(nums2 >= nums3)  # False

元素的遍历

可以使用for-in循环的

languages = ['Python', 'Java', 'C++', 'Kotlin']
for index in range(len(languages)):
    print(languages[index])

输出:

Python
Java
C++
Kotlin

说明:上面的len函数可以获取列表元素的个数N,而range(N)则构成了从0N-1的范围,刚好可以作为列表元素的索引。

直接对列表做循环

languages = ['Python', 'Java', 'C++', 'Kotlin']
for language in languages:  # language是元素
    print(language)

可以用列表的知识来重构上面“掷色子统计每种点数出现次数”的代码。


import random

counters = [0] * 6
# 模拟掷色子记录每种点数出现的次数
for _ in range(6000):
    face = random.randrange(1, 7)
    counters[face - 1] += 1
# 输出每种点数出现的次数
for face in range(1, 7):
    print(f'{face}点出现了{counters[face - 1]}次')

counters列表中的六个元素分别表示 1 到 6 点出现的次数,如果摇出 1 点,counters[0]的值加 1,如果摇出 2 点,counters[1]的值加 1,使得修改后的代码比之前的代码要简单优雅得多。