在开端本节课的内容之前,咱们先给咱们一个编程任务,将一颗色子掷6000
次,计算每种点数呈现的次数。这个任务对咱们来说应该是十分简略的,咱们能够用1
到6
均匀分布的随机数来模仿掷色子,然后用6
个变量别离记录每个点数呈现的次数,信任通过前面的学习,咱们都能比较顺利的写出下面的代码。
"""
将一颗色子掷6000次,计算每种点数呈现的次数
Author: 骆昊
Version: 1.0
"""
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 中咱们能够通过容器类型的变量来保存和操作多个数据,咱们首先为咱们介绍列表(list
)这种新的数据类型。
创立列表
在 Python 中,列表是由一系元素按特定次序构成的数据序列,这就意味着假如咱们界说一个列表类型的变量,能够用它来保存多个数据。在 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]
阐明:列表中能够有重复元素,例如
items1
中的35
;列表中能够有不同类型的元素,例如items3
中有int
类型、float
类型、str
类型和bool
类型的元素,但是咱们通常并不建议将不同类型的元素放在同一个列表中,主要是操作起来极为不方便。
咱们能够运用type
函数来查看变量的类型,有爱好的小伙伴能够自行查看上面的变量items1
到底是什么类型。因为列表能够保存多个元素,它是一种容器型的数据类型,所以咱们在给列表类型的变量起名字时,变量名通常用复数方式的单词。
除此以外,还能够通过 Python 内置的list
函数将其他序列变成列表。准确的说,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']
阐明:
range(1, 10)
会产生1
到9
的整数序列,给到list
结构器中,会创立出由1
到9
的整数构成的列表。字符串是字符构成的序列,上面的list('hello')
用字符串hello
的字符作为列表元素,创立了列表对象。
列表的运算
咱们能够运用+
运算符完成两个列表的拼接,拼接运算会将两个列表中的元素连接起来放到一个列表中,代码如下所示。
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']
咱们能够运用in
或not in
运算符判断一个元素在不在列表中,咱们在上面的代码代码中再增加两行,如下所示。
print(29 in items6) # True
print(99 in items6) # False
print('C++' not in items7) # True
print('Python' not in items7) # False
因为列表中有多个元素,而且元素是按照特定次序放在列表中的,所以当咱们想操作列表中的某个元素时,能够运用[]
运算符,通过在[]
中指定元素的方位来拜访该元素,这种运算称为索引运算。需要阐明的是,[]
的元素方位能够是0
到N - 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', 'strawberry', 'durian', 'peach', 'watermelon']
在运用索引运算的时候要防止呈现索引越界的情况,关于上面的items8
,假如咱们拜访items8[5]
或items8[-6]
,就会引发IndexError
错误,导致程序崩溃,对应的错误信息是:list index out of range,翻译成中文便是“数组索引超出规模”。因为关于只要五个元素的列表items8
,有用的正向索引是0
到4
,有用的反向索引是-1
到-5
。
假如期望一次性拜访列表中的多个元素,咱们能够运用切片运算。切片运算是形如[start:end:stride]
的运算符,其间start
代表拜访列表元素的开端方位,end
代表拜访列表元素的停止方位(停止方位的元素无法拜访),而stride
则代表了跨度,简略的说便是方位的增量,比方咱们拜访的第一个元素在start
方位,那么第二个元素就在start + stride
方位,当然start + stride
要小于end
。咱们给上面的代码增加下面的语句,来运用切片运算符拜访列表元素。
print(items8[1:3:1]) # ['strawberry', 'durian']
print(items8[0:3:1]) # ['apple', 'strawberry', 'durian']
print(items8[0:5:2]) # ['apple', 'durian', 'watermelon']
print(items8[-4:-2:1]) # ['strawberry', 'durian']
print(items8[-2:-6:-1]) # ['peach', 'durian', 'strawberry', 'apple']
提醒:咱们能够看看上面代码中的最后一行,想一想当跨度为负数时,切片运算是如何拜访元素的。
假如start
值等于0
,那么在运用切片运算符时能够将其省略;假如end
值等于N
,N
代表列表元素的个数,那么在运用切片运算符时能够将其省略;假如stride
值等于1
,那么在运用切片运算符时也能够将其省略。所以,下面的代码跟上面的代码效果完全相同。
print(items8[1:3]) # ['strawberry', 'durian']
print(items8[:3:1]) # ['apple', 'strawberry', 'durian']
print(items8[::2]) # ['apple', 'durian', 'watermelon']
print(items8[-4:-2]) # ['strawberry', 'durian']
print(items8[-2::-1]) # ['peach', 'durian', 'strawberry', '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
阐明:上面的
nums1
和nums2
对应元素完全相同,所以==
运算的结果是True
。nums2
和nums3
的比较,因为nums2
的第一个元素1
小于nums3
的第一个元素3
,所以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)
则构成了从0
到N-1
的规模,刚好能够作为列表元素的索引。
办法二:直接对列表做循环,循环变量便是列表元素的代表。
languages = ['Python', 'Java', 'C++', 'Kotlin']
for language in languages:
print(language)
输出:
Python
Java
C++
Kotlin
总结
讲到这儿,咱们能够用列表的常识来重构上面“掷色子计算每种点数呈现次数”的代码。
"""
将一颗色子掷6000次,计算每种点数呈现的次数
Author: 骆昊
Version: 1.1
"""
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
点呈现的次数,最开端的时候六个元素的值都是0
。接下来,咱们用1
到6
均匀分布的随机数模仿掷色子,假如摇出1点,counters[0]
的值加1
,假如摇出2点,counters[1]
的值加1
,以此类推。咱们感受一下,因为运用了列表类型加上循环结构,咱们对数据的处理是批量性的,这就使得修改后的代码比之前的代码要简略优雅得多。