(Python) 嵌套循环中列表遍历?

2 投票
2 回答
767 浏览
提问于 2025-04-16 06:53

我搞不清楚这里发生了什么。我设置了几个列表,每个列表对应一种颜色,里面有它的RGB值,然后还有一个列表colors[],里面包含了每种颜色的列表。接着我用一个嵌套的for循环:外层循环用来创建填充颜色的矩形列,内层循环则是用来推进行数。看起来并不复杂。

我想用numdown来遍历colors[]列表,这样每两行就能换一次颜色,颜色会对应到colors[]里的成员。

问题是,当我使用内层列表的numover时,效果很好,但显然我得到的颜色模式是错的(颜色是横向变化的,而不是纵向的)。如果我用numdown来遍历列表,似乎只有白色这个成员被访问到,尽管在内层for循环中我用'print(numdown)'或者'print(colors[numdown])'时,确实能打印出正确的值。

为什么会这样呢?为什么用内层for循环的numover能正确访问列表成员,而用外层for循环的numdown就不行了呢?

我觉得这可能和pygame有关,不过我也不太清楚具体是什么。

(另外,作为一个刚开始学习Python的人,如果你看到其他值得注意的方法或风格上的问题,请随时指出来。)

import pygame, sys
from pygame.locals import *

#initialize pygame
pygame.init()

#assign display window dimensions
winwidth = 400
winheight = 700

#number of rows, number of colums
numrows = range(1,11)
numcols = range(1,11)

#Keeping brick size proportionate to the window size
brickwidth = winwidth / (len(numrows))  
brickheight = winheight / 4 

#Pixel space above the breakout area
bricktopspace = winheight / 7

#Set display window width, height 
windowSurface = pygame.display.set_mode((winwidth, winheight), 0, 0)

brickxcoord = 0
    blue = [0, 0, 255]  
    green = [0, 255, 0]  
    yellow = [255, 255, 0]  
    red = [255, 0, 0]  
    white = [255, 255, 255]  

    colors = range(0,11)    
    colors[1] = white
    colors[2] = white
    colors[3] = red
    colors[4] = red
    colors[5] = green
    colors[6] = green
    colors[7] = yellow
    colors[8] = yellow
    colors[9] = blue
    colors[10] = blue

    class Setup():

        for numdown in numcols:

            for numover in numrows:

                print(numdown)
                pygame.draw.rect(windowSurface, colors[numdown], (brickxcoord, 
                bricktopspace, brickwidth, brickheight))
                brickxcoord = brickxcoord + brickwidth

            bricktopspace = bricktopspace + brickheight

class Main():

    Setup()
    pygame.display.update()

2 个回答

3

我对pygame的方法不太了解,但有一种更常见的方式来声明列表,那就是

colors = []
colors.append(white)
...

这样做比先创建一个范围再覆盖它要好。你甚至可以这样做

colors = [white, white, ...]

不过那样可能会显得有点复杂。另外,你的第一个列表元素总是在位置“0”,所以你最终得到的列表会是 [0, white, white, ...],而不是 [white, white, ...],因为你是从colors[1]开始定义颜色的。

1

呃……虽然有点晚了,但如果你还在的话,这样可以吗?

我稍微改了一下,但尽量保持和你原来的结构相似:

import pygame, sys
from pygame.locals import *

#assign display window dimensions
winwidth = 400
winheight = 700

#number of rows, number of colums
numrows = 10
numcols = 10

#Keeping brick size proportionate to the window size
brickwidth = winwidth / numcols 
brickheight = winheight / numcols 

#initialize pygame
pygame.init()
#Set display window width, height
windowSurface = pygame.display.set_mode((winwidth, winheight), 0, 0)

#Colours
blue = [0, 0, 255]  
green = [0, 255, 0]  
yellow = [255, 255, 0]
red = [255, 0, 0]  
white = [255, 255, 255]

colours = [white, white, red, red, green, green, yellow, yellow, blue, blue]

class Setup():
    def __init__(self):
        #Setup nest for loop to generate 2d array of blocks.
        for y in range(0, numrows):
            for x in range(0, numcols):
                #Using modulo to get the different colours for rows, we use y as the changing key
                col_index = y % len(colours)
                pygame.draw.rect(windowSurface, colours[col_index], (x*brickwidth, y*brickheight, brickwidth, brickheight))

class Main():
    Setup()
    pygame.display.update()

因为你想要固定的行数和列数,所以你可以用两个变量来表示你需要多少行和多少列。然后你就可以用这些变量来确定每个块的大小,就像你之前做的那样。

我把颜色改成了数组,正如建议的那样,个人觉得这样做也不错(因为这样更简洁,而且可以按顺序读取)。另外,如果你想改变顺序,只需要把这些项目移动一下就行。

最后,我用了两个循环,分别用 numrows 和 numcols 来限制范围。可以把第一个循环想象成行,里面的循环想象成列。就像你的乘法表,包括0,这样就能形成一个完美的网格。

祝你好运!

撰写回答