python中的自调用函数

Cos*_*gia 3 python python-2.7

假设我正在尝试用Python制作BattleShip游戏.我有一个名为board的列表列表.板中的每个列表都是板的那一行中的空格列表,对于这个例子,它将是5x5:

[['clear', 'clear', 'clear', 'clear', 'clear'],
['clear', 'clear', 'clear', 'clear', 'clear'],
['clear', 'clear', 'clear', 'clear', 'clear'],
['clear', 'clear', 'clear', 'clear', 'clear'],
['clear', 'clear', 'clear', 'clear', 'clear']]
Run Code Online (Sandbox Code Playgroud)

我想创建一个函数来返回板中的随机空白区域.

def pl_point(board):
    place = [randrange(0,5),randrange(0,5)] #heh, found out these aren't inclusive.
    if board[place[0]][place[1]] == "clear": return place
    else:
        return pl_point() #calls itself until a clear place is found
Run Code Online (Sandbox Code Playgroud)

以下是我的问题:在获得函数调用之前它是否效率低,直到获得它想要的值(即使电路板几乎完全填满)?我应该采取更好的方式吗?

我无法弄清楚如何使用while语句,因为语句在分配之前总是引用'place',我想不出任何不会引用超出范围的地方的值或未分配的'董事会'价值.

如果这是一个重复的主题我很抱歉,我试图找到一个类似的但不能.这也是我第一次使用这个网站提出问题而不是回答问题.

aba*_*ert 5

函数调用本身是否效率低,直到它获得所需的值(即使电路板几乎完全填满)?我应该采取更好的方式吗?

是的,是的.但问题并不是效率低下,而是如果你不幸需要尝试1000次,那么你的程序会因递归错误而失败.

我无法弄清楚如何使用while语句,因为语句在分配之前总是引用'place',我想不出任何不会引用超出范围的地方的值或未分配的'董事会'价值.

只是使用while True:,你可以breakreturn离开循环:

while True:
    place = [randrange(0,4),randrange(0,4)] #randrange is inclusive
    if board[place[0]][place[1]] == "clear":
        return place
Run Code Online (Sandbox Code Playgroud)

作为一个侧面说明,作为inspectorG4dget在评论中指出的,randrange包括在内; 这将只返回号码0,1,2,和3.

此外,将x和y坐标放入列表中,这样您就可以重复使用[0][1]重复阅读.只需使用x, y = [randrange(5), randrange(5)](解决其他问题),然后board[x][y],和return x, y.


如果这太慢了,那么是的,有更好的方法来做到这一点.首先列出所有清空槽,然后随机选择一个:

clearslots = [(x, y) for x in range(5) for y in range(5) if board[x][y] == "clear"]
return random.choice(clearslots)
Run Code Online (Sandbox Code Playgroud)

当电路板大部分都是空的时,这可能会慢一些,但随着电路板的填满,它不会变得更糟.此外,与您的方法不同,它保证了最坏情况下的恒定时间; 而不是令人难以置信的常规需要多年,这是不可能的.

如果您不理解列表理解,请让我更明确地写出来:

clearslots = []
for x in range(5):
    for y in range(5):
        if board[x][y] == "clear":
            clearslots.append((x, y))
Run Code Online (Sandbox Code Playgroud)

  • `randrange是包容性的`< - 你确定吗?从文档:`从范围中选择一个随机项(开始,停止[,步骤]).这解决了包含端点的randint()的问题; 在Python中,这通常不是你想要的 (2认同)