列表以线性顺序或单一维度跟踪多个信息片段。但是,某些系统(数字图像、棋盘游戏等)的数据存在于二维中。为了可视化这些数据,我们需要一个多维数据结构,即多维列表。
二维列表实际上只不过是列表的列表(三维列表是列表的列表的列表)。想想你的晚餐。你可以有一个一维列表,包含你吃的所有东西:
或者你可以有一个二维列表,包含三道菜,每道菜包含三样你吃的东西:
在列表的情况下,我们传统的一维列表看起来像这样:
myList = [0,1,2,3]
而二维列表看起来像这样:
myList = [ [0,1,2,3], [3,2,1,0], [3,5,6,1], [3,8,3,4] ]
对于我们的目的,最好将二维列表视为矩阵。矩阵可以被认为是一个数字网格,按行和列排列,有点像宾果游戏板。我们可以将二维列表写出来以说明这一点:
myList = [ [0, 1, 2, 3],
[3, 2, 1, 0],
[3, 5, 6, 1],
[3, 8, 3, 4] ]
我们可以使用这种类型的数据结构来编码关于图像的信息。例如,以下灰度图像可以由以下列表表示:
4x4 灰度网格示例
myList = [ [236, 189, 189, 0],
[236, 80, 189, 189],
[236, 0, 189, 80],
[236, 189, 189, 80] ]
要遍历一维列表的每个元素,我们使用 for 循环,即:
myList = [0,1,2,3,4,5,6,7,8,9]
for index in range(len(myList)):
myList[index] = 0 # 将索引处的元素设置为 0
对于二维列表,为了引用每个元素,我们必须使用两个嵌套循环。这为我们提供了矩阵中每列和每行的计数器变量。
myList = [ [0, 1, 2],
[3, 4, 5],
[6, 7, 8] ]
# 两个嵌套循环允许我们访问二维列表中的每个位置。
# 对于每一列 i,访问每一行 j。
for i in range(len(myList)):
for j in range(len(myList[0])):
myList[i][j] = 0
例如,我们可以编写一个使用二维列表绘制灰度图像的程序。
随机噪声示例(每次刷新都会生成不同的图案)
# 示例:二维列表
def setup():
size(200,200)
nRows = height
nCols = width
myList = make2dList(nRows, nCols)
drawPoints(myList)
def make2dList(nRows, nCols):
newList = []
for row in range(nRows):
# 为每个新行提供一个空列表
newList.append([])
for col in range(nCols):
# 使每行中的每列都是 0 到 255 之间的随机整数
newList[row].append(int(random(255)))
return newList
def drawPoints(pointList):
for y in range(len(pointList)):
for x in range(len(pointList[0])):
stroke(pointList[y][x])
rect(x,y,10,10)
二维列表也可以用来存储对象,这对于涉及某种"网格"或"棋盘"的编程草图特别方便。以下示例显示存储在二维列表中的 Cell 对象网格。每个单元格都是一个矩形,其亮度使用正弦函数在 0-255 之间振荡。
动态对象网格示例(每个单元格的亮度会振荡变化)
# 示例:对象二维数组
# 网格中的列数和行数
nCols = 10
nRows = 10
def setup():
global nCols, nRows, grid
size(200,200)
grid = makeGrid()
for i in range(nCols):
for j in range(nRows):
# 初始化每个对象
grid[i][j] = Cell(i*20,j*20,20,20,i+j)
def draw():
global nCols, nRows, grid
background(0)
# 计数器变量 i 和 j 也是列号和行号,
# 并用作网格中每个对象构造函数的参数。
for i in range(nCols):
for j in range(nRows):
# 振荡并显示每个对象
grid[i][j].oscillate()
grid[i][j].display()
# 创建一个 nCols x nRows 大小的二维列表,填充 0
def makeGrid():
global nCols, nRows
grid = []
for i in range(nCols):
# 为每一行创建一个空列表
grid.append([])
for j in range(nRows):
# 用 0 填充每行中的每列
grid[i].append(0)
return grid
# Cell 对象
class Cell():
# 单元格对象知道它在网格中的位置
# 它还通过变量 x,y,w,h 知道它的大小
def __init__(self, tempX, tempY, tempW, tempH, tempAngle):
self.x = tempX
self.y = tempY
self.w = tempW
self.h = tempH
self.angle = tempAngle
# 振荡意味着增加角度
def oscillate(self):
self.angle += 0.02
def display(self):
stroke(255)
# 使用正弦波计算颜色
fill(127+127*sin(self.angle))
rect(self.x,self.y,self.w,self.h)