购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4
使用Python模块

编程领域常说的一句话是不要重复造轮子,因此重用已有的代码是编程设计的重要思想。Python中有大量已经非常完善的类和函数,这些可以重用的类和函数称为模块。在Python中进行游戏编程开发依赖的模块是Pygame,这个模块将在第3章进行介绍。进行AI编程开发的模块是PyTorch,这个模块将在第8章进行介绍。我们还会依赖其他一些模块,对于这些模块我们在此做简单介绍。如果有需要,读者可以通过官网查阅更详细的模块资料。如果本地环境还没有安装这些模块,需要在联网条件下通过pip进行安装。

2.4.1 random模块

如名称的含义所示,random模块用于生成伪随机数。下面的例子中,使用random模块的randint函数,可以生成1~10的任意一个整数数字。随机数的引入可以增强游戏的随机性,让游戏更为有趣。

import random
x=random.randint(1,10)
print(x)

2.4.2 NumPy模块

Python中有一些数据类型,例如列表、字典、集合等,可以用于保存一系列的数据信息。不过对于大规模的数据计算,它们并不都适用。在AI领域的计算中,大规模数据一般以向量形式保存。NumPy模块是专门用于向量计算的模块。让我们看看下面的例子。

首先建立一个列表,再建立一个数组,输出并观察二者的类型,可以看到二者的类型是不一样的。x_list是列表(list)类型的,x_array是NumPy数组类型的。

import numpy as np
x_list=[1,2,3,4]
type(x_list)
list 
x_array=np.array([1,2,3,4])
type(x_array) 
numpy.ndarray

NumPy数组类型的重要特点在于支持向量化计算,例如我们要计算数值的平方再求和,如果使用列表类型,需要写一个循环,或者使用列表解析来完成。

x_sum=0
for x in x_list:
    x_sum=x_sum+x**2
print(x_sum)
30
sum([x**2 for x in x_list])
30 

如果使用NumPy数组类型,则更加简单,它可以直接对每个数值做平方运算。通过这个例子可以看到NumPy数组类型的优点,它的向量化计算非常方便、快速。

sum(x_array**2)
30 

2.4.3 matplotlib模块

matplotlib是Python环境中非常重要的绘图模块。因为AI和大规模数据计算有直接关系,所以我们会主要使用matplotlib模块来观察数据中的规律,以及在游戏编程领域中观察各项AI指标的走向。matplotlib模块的功能非常丰富,我们先用一个例子来了解一下。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

先通过NumPy模块构造两个向量x和y,x表示横坐标的位置,y表示x对应的sin函数值。

x=np.linspace(0,2*3.1415,100)
y=np.sin(x)

使用linspace在0~2π生成100个点,然后用向量化计算直接算出100个点对应的sin函数值,再使用plt.plot绘制基础的线图,表现两个向量之间的函数关系。这种图(如图2-5所示)可以将数据的大小反映到坐标位置上,我们可以很容易地观察到sin函数的规律性波动变化。

plt.plot(x,y)

图2-5

2.4.4 copy模块

Python有一个很重要的特点,就是当我们使用等号进行赋值时,并没有进行复制操作,而仅仅是进行了一次绑定操作。我们来看下面的例子。

x=[1,2,3,4]
y=x
x[0]=100
print(y)
[100,2,3,4] 

可以看到x的第一个元素修改后,y也改变了,因为它们绑定的都是同一个列表对象。代码y=x只是让y变量和已有的列表对象进行了绑定,或者说y只是x的引用。如果一定要进行复制操作,就需要使用copy模块。使用copy模块中的copy函数,y就将x完全复制进行了,不会被x的修改操作所影响。

import copy
x=[1,2,3,4]
y=copy.copy(x)
x[0]=100
print(y)

当x是复合对象时,例如嵌套列表时,情况变得复杂了,此时copy函数进行的是并不完整的复制操作,因为它只能进行所谓的浅复制。

x=[[1,2,3,4],[2,3,4,5]]
y=copy.copy(x)
x[0][0]=100
print(y)
[[100,2,3,4],[2,3,4,5]] 

对于这种情况,我们需要用另一个函数deepcopy,来进行所谓的深复制。

x=[[1,2,3,4],[2,3,4,5]]
y=copy.deepcopy(x)
x[0][0]=100
print(y)
[[1,2,3,4],[2,3,4,5]] 

2.4.5 collections模块

我们还会使用collections模块中的一些数据结构,例如namedtuple类型,它是带有名称的元组。下面的例子中,我们定义了一个几何意义上的点坐标,如果使用传统的元组,需要使用数字编号来取值,使用名称让代码更容易理解。

from collections import namedtuple
Point=namedtuple('Point',['x','y'])
p=Point(11,22)
print(p[0]+p[1])
print(p.x+p.y)

另一个会用到的是deque类型,它也被称为队列,和列表一样,它可以被遍历,也可以增加元素。它的一个重要特点在于,当指定了最大容量后,新增加的元素补充进右侧尾部,最左侧头部的元素则会被删除。这样实现了先进先出的设计需求。 KtBFOTEkuO7VRYMlCDRJOTaUBAqk+/nVR52Uu9z1CVdd5BEbZUuuyKQiWal1230I

from collections import deque
d=deque('ghi',maxlen=4)
d.append('j')
print(d)
d.append('k')
print(d)

   
deque(['g','h','i','j'],maxlen=4)
deque(['h','i','j','k'],maxlen=4)
点击中间区域
呼出菜单
上一章
目录
下一章
×